今天項目中遇到一個問題,一個定時器一段時間就會報錯,一段時間又正常,錯誤如下:
Caused by: org.hibernate.exception.GenericJDBCException: Cannot open connection
at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:103)
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:91)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:29)
at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:426)
at org.hibernate.jdbc.ConnectionManager.getConnection(ConnectionManager.java:144)
at org.hibernate.jdbc.JDBCContext.connection(JDBCContext.java:119)
at org.hibernate.transaction.JDBCTransaction.begin(JDBCTransaction.java:57)
at org.hibernate.impl.SessionImpl.beginTransaction(SessionImpl.java:1326)
at org.hibernate.ejb.TransactionImpl.begin(TransactionImpl.java:38)
... 22 more
Caused by: org.apache.commons.dbcp.SQLNestedException: Cannot get a connection, pool error Timeout waiting for idle object
at org.apache.commons.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:104)
at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:880)
at org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider.getConnection(InjectedDataSourceConnectionProvider.java:47)
at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:423)
... 27 more
Caused by: java.util.NoSuchElementException: Timeout waiting for idle object
at org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:1134)
at org.apache.commons.dbcp.AbandonedObjectPool.borrowObject(AbandonedObjectPool.java:84)
at org.apache.commons.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:96)
很顯然,錯誤的意思是數據庫連接池不夠用了,請求的時候報錯了。通過JVisualVM監控了一下,發現問題
數據源配置如下:
datasource.initialSize=2
datasource.maxActive=2
datasource.maxIdle=2
連接池最大連接數為2,
所以當線程1和線程2還沒跑完的時候,線程3也開始運行調用service的時候就獲取不到session而報錯,以上只是我測試的模擬方案,實際中不會最大連接數為2。
解決方案:調整定時器的執行周期,如果多個線程交叉,需要的鏈接可能不夠用。