Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/359.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 无法打开数据库时Tomcat连接池恢复_Java_Tomcat_Jpa_Spring Batch_Connection Pooling - Fatal编程技术网

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

Java 无法打开数据库时Tomcat连接池恢复,java,tomcat,jpa,spring-batch,connection-pooling,Java,Tomcat,Jpa,Spring Batch,Connection Pooling,我有一个Spring批处理作业,它使用tomcat连接池连接执行一些DAO jpa代码——批处理作业每5分钟运行一次。我的连接池属性看起来像 @Bean(destroyMethod = "close") public javax.sql.DataSource myDataSource() { org.apache.tomcat.jdbc.pool.DataSource ds = new org.apache.tomcat.jdbc.pool.DataSource(); ds.se

我有一个Spring批处理作业,它使用tomcat连接池连接执行一些DAO jpa代码——批处理作业每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;
}
@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();

}
我的刀法看起来像

@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;
}
@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();

}
大多数情况下,此作业运行良好

但是-当SQL Server代理作业执行数据库还原时,每隔一段时间进入单用户模式的数据库每5分钟运行一次此作业。当作业在数据库处于单用户模式下运行时,我会得到一个异常

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


谢谢,敬请指教。

连接池已设置为恢复。如果作业每5分钟运行一次,则下一次运行(当然取决于数据库不可用的时间)将顺利连接并正常运行。如果你想让你的工作在30秒后重试,你需要编码。请记住,当数据库宕机时,工作可能完成了一半,因此如何从中恢复取决于工作。连接池无法重新建立已终止的连接,因为在上一个连接中完成的所有操作都已丢失。该错误似乎来自tomcat连接池进行连接验证,而不是来自批处理作业内部,我不确定如何从中恢复?该错误发生在后台,当Tomcat测试池中的连接时。你的代码还没有失败,所以你还没有问题。如果数据库在下一个作业运行时已完成还原,则它将使用新连接无误地运行。记录的错误并不表示有任何问题(目前)。谢谢,这就解决了很多问题:)