记一次生产环境事务超时

来源:互联网 发布:指绘软件 编辑:程序博客网 时间:2024/06/07 07:16

由于在3.5版本之前,没有使用quartz调度器做定时清理任务,导致数据库操作日志表上已经由十几万条的数据。在3.5之后做了定时清理任务,每晚两点定时执行,清理前30天的数据。以下为实现清理任务的核心代码:

          @Transactional(readOnly = false)

          public void clearExpiredData(Date date) {
List<VmanagerAuditLog> auditLogList = auditLogDAO.getExpiredData(date);
for (VmanagerAuditLog vmanagerOnlineUser : auditLogList) {
auditLogDAO.delete(vmanagerOnlineUser);
}
}


逻辑就是先查询过期数据,然后一条条删除(这代码不是本人写的,那位同事已经离职了)。。

   但是看上去也能正常执行,测试部门之前也测过确实没问题。然后上周,师父跑过来说,数据库去年的数据都还在,叫同事跟一下这个问题。同事心想,肯定是quartz任务没吊起来。然后看了下日志,任务每晚都正常执行,也没有爆出任何异常! 然后看到上述代码时,同事叫我帮他一起看一下问题出在哪。同事怀疑是由于十几万的数据量查出来,存在内存中,导致内存泄漏,然而看日志也没有出现相应的错误。百思不得其解。。

  最后,想到了事务超时,由于这段代码是在一个事务,先经过查询,由于数据量比较庞大,然后再逐一删除,查询跟删除时间都比较久,导致事务超时,最后事务回滚,导致数据没有被删除掉。。最后把代码改为auditLogDAO.deleteByDate(Date expireDate) ; 该段代码的sql就是通过过期时间节点删除该时间点之前的数据。 放到生产环境上。第二天,问题成功解决。


  虽然整体逻辑是没什么问题,但是效率低下。所以不要以为实现功能就好了,低下的效率代码,真不知道会导致什么问题。