最近在项目中遇到
Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.
这个异常经分析是因为mysql默认空闲8小时没有操作会自动断开,这就是问题的所在,在C3P0 pools中的connections如果空闲超过8小时,Mysql将其断开,而C3P0并不知道该connection已经失效,如果这时有Client请求connection,C3P0将该失效的Connection提供给Client,将会造成上面的异常。
解决方案
springboot 的application.properties文件中增加下面DBCP配置
spring.datasource.druid.validation-query=SELECT 1 FROM DUAL
spring.datasource.druid.test-on-borrow=true
spring.datasource.druid.test-on-return=false
spring.datasource.druid.test-while-idle=true
spring.datasource.druid.time-between-eviction-runs-millis=60000
spring.datasource.druid.min-evictable-idle-time-millis=25200000
尤其是test-on-borrow=true,(默认为false),当应用向连接池申请连接时,连接池会判断这条连接是否是可用的。如果为false就很容易出现上面的异常,不过设置成true在高并发的情况下容易造成性能下降,高并发情况下需要设置成false,在业务代码里判断连接是否可用
testWhileIdle建议配置为true。对性能影响很小,因为是定期检查。如果连接空闲时间大于timeBetweenEvictionRunsMillis指定的毫秒,就会执行参数validationQuery指定的SQL来检测连接是否有效。
testOnReturn
建议配置为false。归还连接时执行validationQuery检测连接是否有效,这个配置会降低性能。
另外并不推荐在URL后面添加autoReconnect=true,这个在5.0版本之前有效,5.0之后不生效了