无法打开数据库时Tomcat连接池恢复

时间:2017-05-19 14:25:43

标签: java tomcat jpa spring-batch connection-pooling

我有一个使用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秒到一分钟,直到数据库再次可用,然后尝试重新连接?

谢谢,任何建议表示赞赏。

0 个答案:

没有答案