我有一个使用tomcat连接池连接执行一些DAO jpa代码的Spring Batch作业 - 批处理作业每5分钟运行一次。我的连接池属性类似于
@Bean(destroyMethod = "close")
public javax.sql.DataSource myDataSource() {
org.apache.tomcat.jdbc.pool.DataSource ds = new org.apache.tomcat.jdbc.pool.DataSource();
ds.setDriverClassName(myDriverClass);
ds.setUrl(myUrl);
ds.setUsername(myUsername);
ds.setPassword(myPassword);
ds.setTestWhileIdle(true);
ds.setTestOnBorrow(true);
ds.setTestOnReturn(false);
ds.setValidationInterval(3000);
ds.setTimeBetweenEvictionRunsMillis(5000);
ds.setMaxActive(100);
ds.setInitialSize(10);
ds.setMaxWait(90000);
ds.setMinEvictableIdleTimeMillis(60000);
ds.setMinIdle(10);
//ds.setRemoveAbandonedTimeout(300);
//ds.setLogAbandoned(true);
//ds.setRemoveAbandoned(true);
ds.setJdbcInterceptors(
"org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;"+
//"org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer;"+
"org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer");
ds.setValidationQuery("SELECT TOP 1 * FROM [myDb].[dbo].[tbl_Reports]");
return ds;
}
我的DAO方法看起来像
@PersistenceContext
private EntityManager em;
@Override
public Long getLastVersion(String table_name) {
ChangetableVersions ctv = null;
try {
Query q = em.createQuery("SELECT c FROM ChangetableVersions c WHERE c.tableName = :table_name");
q.setParameter("table_name", table_name);
ctv = (ChangetableVersions) q.getSingleResult();
} catch (Exception e) {
e.printStackTrace();
return Long.valueOf(0);
}
return ctv.getLastVersion();
}
大部分时间这项工作都运行良好。
但是 - 此作业每隔5分钟对一个数据库运行一次,每隔一段时间进入单用户模式,而SQL Server代理作业执行数据库恢复。当作业在数据库处于单用户模式时运行时,我得到一个异常
09:10:20.136 [INFO ] com.company.myagentmonitor.config.myAgentThreadPoolTaskScheduler - Reports Job 1 done
09:13:32.727 [DEBUG] org.apache.tomcat.jdbc.pool.PooledConnection - Unable to validate object:
com.microsoft.sqlserver.jdbc.SQLServerException: Database 'MYDB' cannot be opened. It is in the middle of a restore.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:232)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1672)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.doExecuteStatement(SQLServerStatement.java:903)
at com.microsoft.sqlserver.jdbc.SQLServerStatement$StmtExecCmd.doExecute(SQLServerStatement.java:796)
at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:7535)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:2438)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:208)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:183)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.execute(SQLServerStatement.java:769)
at org.apache.tomcat.jdbc.pool.PooledConnection.validate(PooledConnection.java:532)
at org.apache.tomcat.jdbc.pool.PooledConnection.validate(PooledConnection.java:443)
at org.apache.tomcat.jdbc.pool.ConnectionPool.testAllIdle(ConnectionPool.java:1076)
at org.apache.tomcat.jdbc.pool.ConnectionPool$PoolCleaner.run(ConnectionPool.java:1465)
at java.util.TimerThread.mainLoop(Unknown Source)
at java.util.TimerThread.run(Unknown Source)
如何设置tomcat连接池以便从此异常中恢复?现在我的服务出错了。我想做的是 有tomcat连接池关闭连接,并尝试重新连接 - 如果它不能重新连接,然后等待30秒到一分钟,直到数据库再次可用,然后尝试重新连接?
谢谢,任何建议表示赞赏。