java Spring使用事务性重试
Spring重试是否保证与Spring的@Transactional
注释一起工作
具体地说,我尝试使用@Retryable
进行乐观锁定。这似乎取决于创建的AOP代理的顺序。例如,如果调用如下所示:
呼叫代码->;重试代理->;交易代理->;实际数据库代码
然后它将正常工作,但如果代理的结构如下所示:
呼叫代码->;交易代理->;重试代理->;实际数据库代码
然后重试将不起作用,因为关闭事务的行为会引发optmistic锁定异常
在测试中,它似乎生成了第一个案例(重试,然后是事务),但我无法判断这是一个有保证的行为还是幸运的行为
# 1 楼答案
如果您正在使用Spring Boot,并且希望使用
@Retryable
,则需要执行以下操作:@Retryable
注释您的方法:您可以使用
@Retryable
和@Transactional
对同一方法进行注释,它将按预期工作# 2 楼答案
默认情况下,Spring Retry以相同的最低优先级生成通知-请查看RetryConfiguration。 但是,有一种非常简单的方法可以覆盖此顺序:
确保省略@EnableRetry注释以避免考虑默认RetryConfiguration
# 3 楼答案
如果您想独立地测试它并确定它的行为,那么您可以使用@Transactional@Service,然后是另一个使用transaction one并只添加重试次数的服务
在这种情况下,无论您测试了多少,您都依赖于未记录的行为(注释处理的顺序如何)。根据创建独立Springbean的顺序等,这可能会在小版本之间发生变化。简言之,在同一方法上混合使用@Transactional和@Retry时,您是在问问题
编辑:有一个类似的问题https://stackoverflow.com/a/45514794/1849837用代码回答
在这种情况下,这似乎很好,因为无论顺序是什么(重试然后事务,或事务或重试),可观察的行为都是相同的
# 4 楼答案
在这里找到了答案: https://docs.spring.io/spring/docs/5.0.6.BUILD-SNAPSHOT/spring-framework-reference/data-access.html#transaction-declarative-annotations 表2表明
Transactional
注释的通知的顺序为Ordered.LOWEST_PRECEDENCE
,这意味着只要不重写这些注释的通知顺序,就可以安全地将Retryable
与Transactional
组合起来。换句话说,您可以安全地使用此表单: