Java Spring使用事务性重试
Spring重试是否保证与Spring的Java Spring使用事务性重试,java,spring,spring-data,spring-retry,Java,Spring,Spring Data,Spring Retry,Spring重试是否保证与Spring的@Transactional注释一起工作 具体来说,我尝试使用@Retryable进行乐观锁定。这似乎取决于创建的AOP代理的顺序。例如,如果调用如下所示: 调用代码->重试代理->事务代理->实际数据库代码 然后它将正常工作,但如果代理的结构如下所示: 调用代码->事务代理->重试代理->实际数据库代码 然后重试将不起作用,因为关闭事务的行为会引发optmistic锁定异常 在测试中,它似乎生成了第一个案例(重试,然后是事务),但我无法判断这是一个有保证
@Transactional
注释一起工作
具体来说,我尝试使用@Retryable
进行乐观锁定。这似乎取决于创建的AOP代理的顺序。例如,如果调用如下所示:
调用代码->重试代理->事务代理->实际数据库代码
然后它将正常工作,但如果代理的结构如下所示:
调用代码->事务代理->重试代理->实际数据库代码
然后重试将不起作用,因为关闭事务的行为会引发optmistic锁定异常
在测试中,它似乎生成了第一个案例(重试,然后是事务),但我无法判断这是一个有保证的行为还是仅仅是幸运的行为。如果您想独立测试它并确定它的行为,那么您可能会有@Transactional@Service,然后是另一个使用事务1并只添加重试的服务 在这种情况下,无论您测试了多少,您都依赖于未记录的行为(注释处理的顺序如何)。根据创建独立Springbean的顺序等,这可能会在小版本之间发生变化。简言之,在同一方法上混合使用@Transactional和@Retry时,您是在问问题 编辑:有类似的回答问题与代码
@Retryable(StaleStateException.class)
@Transactional
public void doSomethingWithFoo(Long fooId){
// read your entity again before changes!
Foo foo = fooRepository.findOne(fooId);
foo.setStatus(REJECTED) // <- sample foo modification
} // commit on method end
@Retryable(StaleStateException.class)
@交易的
公共void doSomethingWithFoo(长fooId){
//更改前请再次阅读您的实体!
Foo-Foo=foosrepository.findOne(fooId);
foo.setStatus(拒绝)/在这里找到了答案:
表2表明Transactional
注释的建议的顺序为Ordered.lower_priority
,这意味着只要不重写这些注释的建议顺序,就可以安全地将Retryable
与Transactional
组合在一起。换句话说,您可以请使用以下表格:
@Retryable(StaleStateException.class)
@Transactional
public void performDatabaseActions() {
//Database updates here that may cause an optimistic locking failure
//when the transaction closes
}
默认情况下,Spring Retry以相同的最低优先级生成通知-请查看RetryConfiguration。
但是,有一种非常简单的方法可以覆盖此顺序:
@Configuration
public class MyRetryConfiguration extends RetryConfiguration {
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
}
确保省略@EnableRetry注释,以避免考虑默认的RetryConfiguration。如果您使用的是Spring Boot,并且希望使用@Retryable
,则需要执行以下操作:
将依赖项添加到pom:
org.springframework.retry
春季重试
在Spring引导应用程序中启用重试:
@enablerery//这大概就是我测试的代码,但是如果两个代理被颠倒,行为会不会不同呢?我认为Retryable
本质上创建了一个try/catch(即“around”通知)。因此,如果事务在try/catch之外关闭,那么重试代理就不会捕获异常。(也许我只是不理解Spring Retry在幕后是如何工作的……)我认为,一个更有趣的问题是@Transacional是否可以与@Recover注释的方法一起工作……似乎不行!