Использование `@ Transactional` с` @ Retriable` Spring - PullRequest
0 голосов
/ 11 мая 2019

Я использую данные пружины jpa с @EnableJpaRepositories и повтор пружины с @EnableRetry.

Я хочу повторить транзакционный метод, который вызывает другой транзакционный метод, который получает Oracle DBMS_LOCK, используя хранимую процедуру-обертку: 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;
      }
    };
  }
...