【问题标题】:Trying to understand why @transactional(noROllBackFor .... is not working试图理解为什么 @transactional(noROllBackFor .... 不起作用
【发布时间】: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


【解决方案1】:

在阅读了我原来帖子的答案后,我改用 Spring Retry 并且能够删除我所有的循环代码。该方法现在看起来像这样:

@Transactional
@ConcurrentDBUpdateRetryPolicy
public void deleteSomeData() {
    this.myDAO.deleteTheData();
}

使用自定义注释定义我想要使用的重试策略。您不需要进行自定义注释,但这样做可以让您集中一个通用的重试定义。这是自定义注释:

@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Retryable(
   include = CannotAcquireLockException.class, 
   maxAttempts = 10, 
   backoff = @Backoff(delay = 500, maxDelay = 10000, multiplier = 2, random = true)
)
public @interface ConcurrentDBUpdateRetryPolicy {}

到目前为止,这一直工作得非常顺利。因此,感谢提出建议的人,感谢 Spring Retry 的作者。

【讨论】:

    猜你喜欢
    • 2021-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-22
    • 2019-01-07
    • 1970-01-01
    相关资源
    最近更新 更多