今天项目中遇到一个问题,一个定时器一段时间就会报错,一段时间又正常,错误如下:
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。
解决方案:调整定时器的执行周期,如果多个线程交叉,需要的链接可能不够用。