Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring使用事务性重试_Java_Spring_Spring Data_Spring Retry - Fatal编程技术网

Java Spring使用事务性重试

Java Spring使用事务性重试,java,spring,spring-data,spring-retry,Java,Spring,Spring Data,Spring Retry,Spring重试是否保证与Spring的@Transactional注释一起工作 具体来说,我尝试使用@Retryable进行乐观锁定。这似乎取决于创建的AOP代理的顺序。例如,如果调用如下所示: 调用代码->重试代理->事务代理->实际数据库代码 然后它将正常工作,但如果代理的结构如下所示: 调用代码->事务代理->重试代理->实际数据库代码 然后重试将不起作用,因为关闭事务的行为会引发optmistic锁定异常 在测试中,它似乎生成了第一个案例(重试,然后是事务),但我无法判断这是一个有保证

Spring重试是否保证与Spring的
@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注释的方法一起工作……似乎不行!