使用了druid1.2.4 版本,日志报错,ConcurrentModifyException 提示的是
if (requireDiscard) { if (holder.statementTrace != null) { holder.lock.lock(); try { //报错代码ConcurrentModifyException for (Statement stmt : holder.statementTrace) { JdbcUtils.close(stmt); } } finally { holder.lock.unlock(); } }
this.discardConnection(holder);
}
以下是测试用的配置 maxWait=60000 timeBetweenEvictionRunsMillis=60000 minEvictableIdleTimeMillis=300000 validationQuery=SELECT 1 FROM DUAL testWhileIdle=true testOnBorrow=true initialSize=1 maxActive=2
原提问者GitHub用户Eatin
据您提供的信息,您使用的是 Druid 数据库连接池 1.2.4 版本,在应用程序中出现了 ConcurrentModifyException 异常。这种异常通常表示在并发访问时,多个线程同时修改了同一个对象,导致数据不一致或冲突。
从您提供的异常信息和代码片段来看,这个异常可能是由于多个线程同时尝试关闭同一个 Statement 对象,导致出现冲突。Druid 数据库连接池中的 Holder 对象保存了连接池中的连接和语句对象,当关闭连接或语句对象时,需要先获取对应的 Holder 对象,然后再进行关闭操作。如果多个线程同时关闭同一个 Holder 对象,就可能出现冲突,导致 ConcurrentModifyException 异常。
为了避免这种异常,建议在多线程环境下,对 Holder 对象进行同步控制。在 Druid 数据库连接池中,每个 Holder 对象都有一个 lock 锁对象,可以在多线程访问时使用该锁对象进行同步控制。
ConcurrentModifyException异常通常在遍历集合的同时对集合进行修改时抛出。在您的代码中,可能存在多个线程同时对holder.statementTrace进行修改的情况,导致了该异常的发生。
为了解决这个问题,您可以考虑使用线程安全的集合或采取同步措施来避免并发修改。在Druid连接池的代码中,holder.statementTrace可能是一个非线程安全的集合。您可以尝试使用并发容器(如CopyOnWriteArrayList)来替换holder.statementTrace,以确保在遍历集合时对其进行修改不会导致异常。
麻烦发一下异常堆栈。 看了一下这里的代码,没发现有会并发修改的地方。
btw:testOnBorrow打开的时候,testWhileIdle为true无效。
原回答者GitHub用户kimmking
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。