c3p0数据库连接池死锁问题和mysql重连,连接丢失

本文详细介绍了在使用c3p0数据库连接池时遇到的死锁问题,以及针对MySQL连接丢失的重连配置。通过调整c3p0的参数设置,如maxIdleTime、testConnectionOnCheckin和preferredTestQuery等,可以避免连接池死锁并确保在空闲超时后能够自动重连。同时,对于多数据库源的情况,需要注意连接管理和超时设置,以防止连接丢失和性能问题。
摘要由CSDN通过智能技术生成

c3p0参数解释

#最常用配置
#initialPoolSize:连接池初始化时创建的连接数,default : 3,取值应在minPoolSize与maxPoolSize之间
c3p0.initialPoolSize=10
#minPoolSize:连接池保持的最小连接数,default : 3
c3p0.minPoolSize=10
#maxPoolSize:连接池中拥有的最大连接数,如果获得新连接时会使连接总数超过这个值则不会再获取新连接,而是等待其他连接释放,所以这个值有可能会设计地很大,default : 15
c3p0.maxPoolSize=50
#acquireIncrement:连接池在无空闲连接可用时一次性创建的新数据库连接数,default : 3
c3p0.acquireIncrement=5
#管理连接池的大小和连接的生存时间
#maxIdleTime:连接的最大空闲时间,如果超过这个时间,某个数据库连接还没有被使用,则会断开掉这个连接。如果为0,则永远不会断开连接,即回收此连接。default : 0 单位 s建议:不能设置太短,否则连接会被频繁的丢弃。
c3p0.maxIdleTime=600
#idleConnectionTestPeriod:每900秒检查所有连接池中的空闲连接
c3p0.idleConnectionTestPeriod=900
#重连相关配置 
#acquireRetryAttempts:连接池在获得新连接失败时重试的次数,如果小于等于0则无限重试直至连接获得成功。default : 30(建议使用)
c3p0.acquireRetryAttempts=5
#acquireRetryDelay:两次连接中间隔时间,单位毫秒,连接池在获得新连接时的间隔时间。default : 1000 单位ms(建议使用)
c3p0.acquireRetryDelay=1000
#breakAfterAcquireFailure:如果为true,则当连接获取失败时自动关闭数据源,除非重新启动应用程序。所以一般不用。default : false(不建议使用)
c3p0.breakAfterAcquireFailure=false
#checkoutTimeout:配置当连接池所有连接用完时应用程序getConnection的等待时间。为0则无限等待直至有其他连接释放或者创建新的连接,单位毫秒。不为0则当时间到的时候如果仍没有获得连接,则会抛出SQLException。其实就是acquireRetryAttempts*acquireRetryDelay。default : 0(与上面两个,有重复,选择其中两个都行)
c3p0.checkoutTimeout=100
#其他
#autoCommitOnClose:连接池在回收数据库连接时是否自动提交事务。如果为false,则会回滚未提交的事务,如果为true,则会自动提交事务。default : false(不建议使用)
c3p0.autoCommitOnClose=false
#c3p0是异步操作的,缓慢的JDBC操作通过帮助进程完成。扩展这些操作可以有效的提升性能 通过多线程实现多个操作同时被执行。Default: 3
c3p0.numHelperThreads=10

最近项目中用的C3P0连接池出现各种bug,现在记录一下。

1、经常报连接池死锁

2016-08-31 15:24:00 [ WARN] - [com.mchange.v2.async.ThreadPoolAsynchronousRunner|run] - com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@74a7d985 -- APPARENT DEADLOCK!!! Complete Status: 
    ⇒  	Managed Threads: 3
    ⇒  	Active Threads: 3
    ⇒  	Active Tasks: 
    ⇒  	com.mchange.v2.c3p0.stmt.GooGooStatementCache$1StatementCloseTask@115721ba (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2)
    ⇒  	com.mchange.v2.c3p0.stmt.GooGooStatementCache$1StmtAcquireTask@6f67433a (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0)
    ⇒  	com.mchange.v2.c3p0.stmt.GooGooStatementCache$1StatementCloseTask@646ecdf9 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1)
    ⇒  	Pending Tasks: 
    ⇒  	com.mchange.v2.resourcepool.BasicResourcePool$1RefurbishCheckinResourceTask@2694c9f2
    ⇒  	com.mchange.v2.c3p0.stmt.GooGooStatementCache$1StmtAcquireTask@725642a7
    ⇒  	com.mchange.v2.resourcepool.BasicResourcePool$AsyncTestIdleResourceTask@7d321c95
    ⇒  	com.mchange.v2.resourcepool.BasicResourcePool$AsyncTestIdleResourceTask@64f2ba69
    ⇒  Pool thread stack traces:
    ⇒  	Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2,5,main]
    ⇒  	com.mysql.jdbc.ResultSetImpl.realClose(ResultSetImpl.java:7337)
    ⇒  	com.mysql.jdbc.ResultSetImpl.close(ResultSetImpl.java:922)
    ⇒  	com.mysql.jdbc.StatementImpl.realClose(StatementImpl.java:2528)
    ⇒  	com.mysql.jdbc.PreparedStatement.realClose(PreparedStatement.java:3036)
    ⇒  	com.mysql.jdbc.StatementImpl.close(StatementImpl.java:577)
    ⇒  	com.mchange.v1.db.sql.StatementUtils.attemptClose(StatementUtils.java:41)
    ⇒  	com.mchange.v2.c3p0.stmt.GooGooStatementCache$1StatementCloseTask.run(GooGooStatementCache.java:404)
    ⇒  	com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)
    ⇒  	Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0,5,main]
    ⇒  	com.mysql.jdbc.PreparedStatement.initializeFromParseInfo(PreparedStatement.java:2944)
    ⇒  	com.mysql.jdbc.PreparedStatement.<init>(PreparedStatement.java:926)
    ⇒  	com.mysql.jdbc.JDBC4PreparedStatement.<init>(JDBC4PreparedStatement.java:47)
    ⇒  	sun.reflect.GeneratedConstructorAccessor63.newInstance(Unknown Source)
    ⇒  	sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    ⇒  	java.lang.reflect.Constructor.newInstance(Constructor.java:526)
    ⇒  	com.mysql.jdbc.Util.handleNewInstance(Util.java:409)
    ⇒  	com.mysql.jdbc.PreparedStatement.getInstance(PreparedStatement.java:842)
    ⇒  	com.mysql.jdbc.ConnectionImpl.clientPrepareStatement(ConnectionImpl.java:1588)
    ⇒  	com.mysql.jdbc.ConnectionImpl.prepareStatement(ConnectionImpl.java:4604)
    ⇒  	com.mysql.jdbc.ConnectionImpl.prepareStatement(ConnectionImpl.java:4502)
    ⇒  	com.mysql.jdbc.LoadBalancedMySQLConnection.prepareStatement(LoadBalancedMySQLConnection.java:2207)
    ⇒  	sun.reflect.GeneratedMethodAccessor45.invoke(Unknown Source)
    ⇒  	sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    ⇒  	java.lang.reflect.Method.invoke(Method.java:606)
    ⇒  	com.mysql.jdbc.LoadBalancingConnectionProxy.invoke(LoadBalancingConnectionProxy.java:651)
    ⇒  	com.mysql.jdbc.LoadBalancingConnectionProxy.invoke(LoadBalancingConnectionProxy.java:556)
    ⇒  	com.sun.proxy.$Proxy52.prepareStatement(Unknown Source)
    ⇒  	com.mysql.jdbc.ReplicationConnection.prepareStatement(ReplicationConnection.java:637)
    ⇒  	com.mysql.fabric.jdbc.FabricMySQLConnectionProxy.prepareStatement(FabricMySQLConnectionProxy.java:766)
    ⇒  	sun.reflect.GeneratedMethodAccessor45.invoke(Unknown Source)
    ⇒  	sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    ⇒  	java.lang.reflect.Method.invoke(Method.java:606)
    ⇒  	com.mchange.v2.c3p0.stmt.GooGooStatementCache$1StmtAcquireTask.run(GooGooStatementCache.java:525)
    ⇒  	com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)
    ⇒  	Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1,5,main]
    ⇒  	com.mysql.jdbc.PreparedStatement.realClose(PreparedStatement.java:3021)
    ⇒  	com.mysql.jdbc.StatementImpl.close(StatementImpl.java:577)
    ⇒  	com.mchange.v1.db.sql.StatementUtils.attemptClose(StatementUtils.java:41)
    ⇒  	com.mchange.v2.c3p0.stmt.GooGooStatementCache$1StatementCloseTask.run(GooGooStatementCache.java:404)
    ⇒  	com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)

使用第二种最新版本的包:


<dependency>
    <groupId>com.mchange</groupId>
    <artifactId>c3p0</artifactId>
    <version>0.9.5.2</version>
</dependency>

这种数据库连接池线程死锁的问题发生的原因可能有很多,我将我的配置环境以及解决方法贴出来供大家参考一下:

使用环境,spring + c3p0

esp.c3p0.url=${esp.c3p0.url}
esp.c3p0.user=${esp.c3p0.user}
esp.c3p0.password=${esp.c3p0.password}

esp_question.c3p0.url=${esp_question.c3p0.url}
esp_question.c3p0.user=${esp_question.c3p0.user}
esp_question.c3p0.password=${esp_question.c3p0.pa

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值