开发者社区> 问答> 正文

1.2.4 ConcurrentModifyException

使用了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

展开
收起
山海行 2023-07-05 17:49:42 60 0
3 条回答
写回答
取消 提交回答
  • 北京阿里云ACE会长

    据您提供的信息,您使用的是 Druid 数据库连接池 1.2.4 版本,在应用程序中出现了 ConcurrentModifyException 异常。这种异常通常表示在并发访问时,多个线程同时修改了同一个对象,导致数据不一致或冲突。

    从您提供的异常信息和代码片段来看,这个异常可能是由于多个线程同时尝试关闭同一个 Statement 对象,导致出现冲突。Druid 数据库连接池中的 Holder 对象保存了连接池中的连接和语句对象,当关闭连接或语句对象时,需要先获取对应的 Holder 对象,然后再进行关闭操作。如果多个线程同时关闭同一个 Holder 对象,就可能出现冲突,导致 ConcurrentModifyException 异常。

    为了避免这种异常,建议在多线程环境下,对 Holder 对象进行同步控制。在 Druid 数据库连接池中,每个 Holder 对象都有一个 lock 锁对象,可以在多线程访问时使用该锁对象进行同步控制。

    2023-07-30 21:19:39
    赞同 展开评论 打赏
  • ConcurrentModifyException异常通常在遍历集合的同时对集合进行修改时抛出。在您的代码中,可能存在多个线程同时对holder.statementTrace进行修改的情况,导致了该异常的发生。

    为了解决这个问题,您可以考虑使用线程安全的集合或采取同步措施来避免并发修改。在Druid连接池的代码中,holder.statementTrace可能是一个非线程安全的集合。您可以尝试使用并发容器(如CopyOnWriteArrayList)来替换holder.statementTrace,以确保在遍历集合时对其进行修改不会导致异常。

    2023-07-09 10:13:52
    赞同 展开评论 打赏
  • 麻烦发一下异常堆栈。 看了一下这里的代码,没发现有会并发修改的地方。

    btw:testOnBorrow打开的时候,testWhileIdle为true无效。

    原回答者GitHub用户kimmking

    2023-07-06 10:36:10
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载