我通过让2个函数以相反的顺序在mysql表中锁定2行来创建死锁情况。我在两个函数上都有@Transactional。我在这两个函数上都有一个aspectj方面,它最多重试2次失败。
死锁后,一个线程成功,一个线程失败。失败的一个重试。到现在为止还挺好。但是,在此之后有两个问题。
当第二次重试失败的功能时,它再次读取2行。但是,第一个的值是旧的,第二个是新的。
最后,事务失败,因为事务已标记为回滚。所以@Transactional代理围绕重试代理。有没有办法扭转秩序?我试图让retry代理继承Ordered并将顺序设置为Ordered.HIGHEST_VALUE和Ordered.LOWEST_VALUE但是都没有工作。
答案 0 :(得分:1)
我试过弹簧重试,它就像一个魅力。仍然在研究它是如何做到这一点的神奇。
我基本上是这样做的:
在org.springframework.retry spring-retry
上添加依赖项将@EnableRetry添加到应用程序
在上面添加@Retryable(maxAttempts = 3,backoff = @Backoff(延迟= 2000)) @Transactional注释函数。
答案 1 :(得分:0)
这个答案更直接:
Intercepting @Transactional After Optimistic Lock for Asynchronous Calls in Restful App
刚刚在方面下方添加了@Order(1)。
原来关键是使用1作为订单。我再次尝试了Ordered接口,就像在问题描述中一样。这次使用1,它与Order注释的工作方式相同,只是界面的快捷方式。