1. 程式人生 > >Quartz叢集資料庫連線失效

Quartz叢集資料庫連線失效

一、問題描述

[2018-6-5 13:57:11] [WARN ] [com.mchange.v2.c3p0.impl.NewPooledConnection:425] - [c3p0] A PooledConnection that has already signalled a Connection error is still in use!

[2018-6-5 13:57:11] [WARN ] [com.mchange.v2.c3p0.impl.NewPooledConnection:426] - [c3p0] Another error has occurred [ com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed. ] which will not be reported to listeners!
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62
) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at com.mysql.jdbc.Util.handleNewInstance(Util.java:404) at com.mysql.jdbc.Util.getInstance(Util.java:387) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:917
) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:896) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:885) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:860) at com.mysql.jdbc.ConnectionImpl.throwConnectionClosedException(ConnectionImpl.java:1235) at com.mysql.jdbc.ConnectionImpl.checkClosed(ConnectionImpl.java:1230
) at com.mysql.jdbc.ConnectionImpl.setAutoCommit(ConnectionImpl.java:4833) at com.mchange.v2.c3p0.impl.NewProxyConnection.setAutoCommit(NewProxyConnection.java:881) at org.quartz.impl.jdbcjobstore.AttributeRestoringConnectionInvocationHandler.restoreOriginalAtributes(AttributeRestoringConnectionInvocationHandler.java:141) at org.quartz.impl.jdbcjobstore.JobStoreSupport.cleanupConnection(JobStoreSupport.java:3600) at org.quartz.impl.jdbcjobstore.JobStoreSupport.doRecoverMisfires(JobStoreSupport.java:3206) at org.quartz.impl.jdbcjobstore.JobStoreSupport$MisfireHandler.manage(JobStoreSupport.java:3935) at org.quartz.impl.jdbcjobstore.JobStoreSupport$MisfireHandler.run(JobStoreSupport.java:3956) Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

二、問題分析

c3p0

Mysql伺服器預設的“wait_timeout”是8小時,也就是說一個connection空閒超過8個小時,Mysql將自動斷開該connection

這就是問題的所在,在C3P0 pools中的connections如果空閒超過8小時,Mysql將其斷開,而C3P0並不知道該connection已經失效,如果這時有Client請求connection,C3P0將該失效的Connection提供給Client,將會造成上面的異常。

而c3p0屬性

<property name="maxIdleTime">60</property>

Quartz

quartz定時任務使用的是預設是maxIdleTime=0,永不丟棄。
從日誌檔案列印quartz資料庫配置資訊來看:

Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ 
acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 
1000, autoCommitOnClose -> false, automaticTestTable -> null, 
breakAfterAcquireFailure -> false, checkoutTimeout -> 0, 
connectionCustomizerClassName -> null, connectionTesterClassName -> 
com.mchange.v2.c3p0.impl.DefaultConnectionTester, dataSourceName -> 
1bqrhug9v1mimg6ddv5dda|8cf8fc3, debugUnreturnedConnectionStackTraces -> 
false, description -> null, driverClass -> com.mysql.jdbc.Driver, 
factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, 
identityToken -> 1bqrhug9v1mimg6ddv5dda|8cf8fc3, idleConnectionTestPeriod 
-> 0, initialPoolSize -> 3, jdbcUrl -> jdbc:mysql://cashbus-test-
vpc.mysql.rds.aliyuncs.com:3306/hdd?useUnicode=true&characterEncoding=utf-
8&zeroDateTimeBehavior=convertToNull, lastAcquisitionFailureDefaultUser -> 
null, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime 
-> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 30, maxStatements 
-> 0, maxStatementsPerConnection -> 120, minPoolSize -> 1, 
numHelperThreads -> 3, numThreadsAwaitingCheckoutDefaultUser -> 0, 
preferredTestQuery -> null, properties -> {user=******, password=******}, 
propertyCycle -> 0, testConnectionOnCheckin -> false, 
testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, 
usesTraditionalReflectiveProxies -> false ]

重點:maxIdleTime -> 0

三、解決方案

加上最大空閒時間,設定為60s

quartz的屬性配置是discardIdleConnectionsSeconds:
org.quartz.dataSource.myDS.discardIdleConnectionsSeconds:60