我在@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;
}
};
}