我使用注入式实体管理工厂执行计划操作:
@PersistenceUnit
private EntityManagerFactory entityManagerFactory;
@Scheduled(cron="0 0/10 * * * *")
private void scheduledOperation() {
int rows = 0;
try {
EntityManager em = entityManagerFactory.createEntityManager();
em.getTransaction().begin();
rows = em.createNativeQuery("UPDATE table SET ...").executeUpdate();
em.getTransaction().commit();
} catch (Exception ex) {
logger.error("Exception while scheduledOperation. Details: " + ex.getMessage());
}
DateTime now = new DateTime(DateTimeZone.UTC);
logger.info("Scheduled operation completed. Rows affected: {}. UTC time: {}", rows, now);
}
当应用程序启动时,计划的操作每10分钟运行一次。所以前几次操作也能正常工作,但过了一段时间,这个错误就消失了:
ERROR - ConnectionHandle - Database access problem. Killing off this
connection and all remaining connections in the connection pool. SQL State = 08S01
会发生什么?如何保持连接,或为每个计划的操作建立工作连接?
最佳答案
这是因为您从未关闭EntityManager,并且关联的连接可能会无限期挂起。
将代码改为:
EntityManager em = null;
try {
em = entityManagerFactory.createEntityManager();
em.getTransaction().begin();
rows = em.createNativeQuery("UPDATE table SET ...").executeUpdate();
em.getTransaction().commit();
} catch (Exception ex) {
logger.error("Exception while scheduledOperation. Details: " + ex.getMessage());
em.getTransaction().rollback();
} finally {
if(em != null) {
em.close();
}
}
失败时总是调用rollback。不要假设事务会自动回滚,因为这是特定于数据库的实现。
关于java - 在Spring中使用BoneCP进行调度操作时,连接断开:“数据库访问问题。终止这种连接……”,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26084797/