【发布时间】:2015-05-21 08:17:02
【问题描述】:
我有一些看起来像这样的代码:
@Transactional(noRollbackFor = { CannotAcquireLockException.class, LockAcquisitionException.class })
public void deleteSomeData() {
int backOffTime = 0;
int fibonacci = 1;
boolean executed = false;
do {
try {
this.myDAO.deleteTheData();
executed = true;
} catch (RuntimeException rt) {
int newBackoffTime = backOffTime + fibonacci;
fibonacci = backOffTime;
backOffTime = newBackoffTime;
try {
Thread.sleep(backOffTime * 100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
} while (!executed);
}
这是在 Spring/JPA 环境中运行的。代码由多个 Quartz 驱动的任务运行,这些任务在不同的时间触发,有时同时触发。因此,如果抛出死锁异常,我试图通过在延迟后重新执行更新代码来解决正在发生的数据库(MySQL)死锁。
我一直在尝试各种事情,并阅读了很多关于事务、死锁等的帖子。
问题是如果this.myDAO.deleteTheData(); 抛出CannotAcquireLockException 那么事务被标记为需要回滚。我正在尝试做的是等待一段时间,然后再次尝试更新。然而,由于回滚状态,第二次尝试失败。因此,如果抛出此异常,我会尝试停止将事务设置为需要回滚。
我不确定我的脑子里有没有这一切,而且这段代码不起作用。该事务仍被标记为需要回滚。
我可以将循环代码移到调用此方法的代码中,这样就无需担心事务,但是这将涉及大量重复代码执行,我想尽量保持这种情况尽可能到数据库。
关于我在哪里出错的任何建议?
【问题讨论】:
-
看看这个答案,它可能对你有帮助:stackoverflow.com/questions/1762870/…
-
你的 DAO 中有
@Transactional注释吗? -
从 dao 中删除
@Transactional。另外,我建议不要自己实现,而是使用spring-retry。 -
DAO 中没有 @Transactioal。我会尝试弹簧重试。
标签: java spring jpa transactions