在Spring的@Retriable中使用@Transactional

时间:2019-05-11 20:35:40

标签: spring-data-jpa spring-data spring-transactions

我在@EnableJpaRepositories中使用spring数据jpa,在@EnableRetry中使用spring重试。

我想重试一个事务方法,该方法调用另一个使用包装器存储的过程DBMS_LOCK获取Oracle MY_PROC_THAT_CALLS_ORACLE_DBMS_LOCK的事务方法。

获取的锁设置为在提交事务时释放,这就是我想要的。

但是,尽管成功获得了第二次尝试的锁定,但我的交易仍被标记为rollback_only,并且失败了。

我怀疑我的存储库中@Transactional方法上的acquireDbmsLock注释正在看到SQLException并将事务设置为仅回滚。

根据我对事务传播语义的理解,我认为我不希望@Transactional(propogation = Propogation.REQUIRES_NEW)接口方法上的acquireDbmsLock。似乎Hibernate不支持Propogation.NESTED

那么,什么是解决此问题的好方法?

我拒绝设置noRollbackFor = SQLException.class

这是我的代码:

@Retriable(SQLException.class)
@Transactional
public MyThing myService(String thingId) {
  MyThing myThing = myRepository.findMyThing(thingId);

  if(myThing == null) {
    myLockRepository.acquireDbmsLock(thingId);
    myRepository.createMyThing(thingId);
  } else {
    return myThing;
  }
}
public interface MyLockRepository extends Repository<XXX, YY> {

  @Procedure(procedureName = "MY_PROC_THAT_CALLS_ORACLE_DBMS_LOCK")
  void acquireDbmsLock(String lockName);
}

我也尝试覆盖默认的重试配置,如下所示(在删除@EnableRetry注释之后):

@Bean
  RetryConfiguration retryConfiguration() {
    // Need retries to happen before transaction is set to rollback only: https://stackoverflow.com/a/53654301/499635
    return new RetryConfiguration() {
      @Override
      public int getOrder() {
       return Ordered.HIGHEST_PRECEDENCE;
      }
    };
  }

0 个答案:

没有答案