Spring 数据 JPA 关闭连接
Spring Data JPA Closed Connection
有一个函数在开始时在数据库中插入一条状态为 "Running" 的记录,然后进行一些长时间的处理,最后将状态更新为 "Success" 或 "failed".
我最后在更新状态时遇到错误,因为处理花费了很长时间(将数据上传到第三方应用程序需要 4 小时)。
java.sql.BatchUpdateException: ORA-02396: exceeded maximum idle time, please connect again
SQL: update STATUS set status=?
o.h.engine.jdbc.spi.SqlExceptionHelper : ORA-02396: exceeded maximum idle time, please connect again
ERROR [-,f292b6c9becb8716,f292b6c9becb8716,false] 13556 --- [nio-8080-exec-7] o.h.i.ExceptionMapperStandardImpl : HHH000346: Error during managed flush [org.hibernate.exception.GenericJDBCException: could not execute batch]
WARN [-,f292b6c9becb8716,f292b6c9becb8716,false] 13556 --- [nio-8080-exec-7] com.zaxxer.hikari.pool.ProxyConnection : HikariPool-2 - Connection oracle.jdbc.driver.T4CConnection@7fb2645b marked as broken because of SQLSTATE(08003), ErrorCode(17008)
java.sql.SQLRecoverableException: Closed Connection
at oracle.jdbc.driver.PhysicalConnection.getAutoCommit(PhysicalConnection.java:1828)
at oracle.jdbc.driver.PhysicalConnection.rollback(PhysicalConnection.java:1953)
at com.zaxxer.hikari.pool.ProxyConnection.rollback(ProxyConnection.java:377)
at com.zaxxer.hikari.pool.HikariProxyConnection.rollback(HikariProxyConnection.java)
at org.hibernate.resource.jdbc.internal.AbstractLogicalConnectionImplementor.rollback(AbstractLogicalConnectionImplementor.java:116)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.rollback(JdbcResourceLocalTransactionCoordinatorImpl.java:251)
at org.hibernate.engine.transaction.internal.TransactionImpl.rollback(TransactionImpl.java:100)
我该如何处理这种情况?
下面是我的代码片段:
public void upload() {
entity.setStatus("RUNNING");
repository.save(entity);
try {
//Uploads data to thrid party;
callingThridPartyApp();
log.info("Upload successfull.");
entity.setStatus("SUCCESS");
repository.save(entity);
} catch (Exception e) {
log.error("Upload failed.", e);
entity.setStatus("FAILED");
repository.save(entity);
}
}
我通过在漫长的过程结束时声明一个新事务来更新数据库中的状态来解决这个问题。
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void updateStatus(Entity entity) {
log.info("Upload successfull.");
entity.setStatus("SUCCESS");
repository.save(entity);
} catch (Exception e) {
log.error("Upload failed.", e);
entity.setStatus("FAILED");
repository.save(entity);
}
}
有一个函数在开始时在数据库中插入一条状态为 "Running" 的记录,然后进行一些长时间的处理,最后将状态更新为 "Success" 或 "failed".
我最后在更新状态时遇到错误,因为处理花费了很长时间(将数据上传到第三方应用程序需要 4 小时)。
java.sql.BatchUpdateException: ORA-02396: exceeded maximum idle time, please connect again
SQL: update STATUS set status=?
o.h.engine.jdbc.spi.SqlExceptionHelper : ORA-02396: exceeded maximum idle time, please connect again
ERROR [-,f292b6c9becb8716,f292b6c9becb8716,false] 13556 --- [nio-8080-exec-7] o.h.i.ExceptionMapperStandardImpl : HHH000346: Error during managed flush [org.hibernate.exception.GenericJDBCException: could not execute batch]
WARN [-,f292b6c9becb8716,f292b6c9becb8716,false] 13556 --- [nio-8080-exec-7] com.zaxxer.hikari.pool.ProxyConnection : HikariPool-2 - Connection oracle.jdbc.driver.T4CConnection@7fb2645b marked as broken because of SQLSTATE(08003), ErrorCode(17008)
java.sql.SQLRecoverableException: Closed Connection
at oracle.jdbc.driver.PhysicalConnection.getAutoCommit(PhysicalConnection.java:1828)
at oracle.jdbc.driver.PhysicalConnection.rollback(PhysicalConnection.java:1953)
at com.zaxxer.hikari.pool.ProxyConnection.rollback(ProxyConnection.java:377)
at com.zaxxer.hikari.pool.HikariProxyConnection.rollback(HikariProxyConnection.java)
at org.hibernate.resource.jdbc.internal.AbstractLogicalConnectionImplementor.rollback(AbstractLogicalConnectionImplementor.java:116)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.rollback(JdbcResourceLocalTransactionCoordinatorImpl.java:251)
at org.hibernate.engine.transaction.internal.TransactionImpl.rollback(TransactionImpl.java:100)
我该如何处理这种情况?
下面是我的代码片段:
public void upload() {
entity.setStatus("RUNNING");
repository.save(entity);
try {
//Uploads data to thrid party;
callingThridPartyApp();
log.info("Upload successfull.");
entity.setStatus("SUCCESS");
repository.save(entity);
} catch (Exception e) {
log.error("Upload failed.", e);
entity.setStatus("FAILED");
repository.save(entity);
}
}
我通过在漫长的过程结束时声明一个新事务来更新数据库中的状态来解决这个问题。
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void updateStatus(Entity entity) {
log.info("Upload successfull.");
entity.setStatus("SUCCESS");
repository.save(entity);
} catch (Exception e) {
log.error("Upload failed.", e);
entity.setStatus("FAILED");
repository.save(entity);
}
}