我使用注入式实体管理工厂执行计划操作:

@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/

10-11 22:22
查看更多