我使用注入的EntityManagerFactory进行预定操作:
@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
什么事发生?我如何保持连接,或为每个预定的操作保持工作连接?
答案 0 :(得分:2)
那是因为你永远不会关闭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。不要假设事务会自动回滚,因为这是一个特定于数据库的实现。