Spring @Transactional аннотация не работает в цикле for с использованием try catch - PullRequest
0 голосов
/ 07 февраля 2019

Мой вопрос приведен ниже. Код псевдокода указан ниже :

public Object rollBackTestMainMethod(List<Object> list) {

  List<Object> responseList = new ArrayList<>();

  for(Object item:list){

    try{    
      Boolean isOperationSuccess = rollBackTestSubMethod(item);
      if (isOperationSuccess==null || !isOperationSuccess){
        item.addError("Operation failed");
        item.addSuccess(false);
      } else {
        item.addError(null);
        item.addSuccess(true);
      }

    } catch(Exception exception) {
      item.addError(exception.getMessage());
      item.addSuccess(false);
    }

    responseList.add(item);
  }

  return responseList;
}

@Transactional(rollbackFor = {Exception.class, SQLException.class})
private Boolean rollBackTestSubMethod(Object listItem){

  Long value1=save(listItem.getValue1());
  if(value1==null){
    throw new Exception("Error during save 1");
  }

  Long value2=save(listItem.getValue2());
  if(value2==null){
    throw new Exception("Error during save 2");
  }
  Long value3=save(listItem.getValue3());
  if(value3==null){
    throw new Exception("Error during save 3");
  }

  return Boolean.TRUE;
}

Что я здесь делаю:

  1. Повтор списка в rollBackTestMainMethod().Отправка одного элемента списка в rollBackTestSubMethod() и выполнение операции сохранения 3.
  2. Если все сохранение завершено, то возвращается истинный ответ, в противном случае выдается исключение.
  3. В rollBackTestMainMethod(), после получения ответа илиИсключение составляет добавление ошибки или успешного значения для каждого элемента.
  4. Добавление этого элемента в новый список с именем responseList.После всех операций он отправляет это обратно как ответ.

Мои вопросы:

  1. После броска с rollBackTestSubMethod() он не будет откатываться назад, поскольку он вызывает из блока try catch.
  2. Если я хочу принудительно выполнить откат с помощью TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();, тогда будет выполнен откат всех элементов для любого броска / исключения.
  3. Здесь требуется откат только для элемента броска, а не для всех элементов.
  4. Этот метод в пружинном бобе
  5. Я сохраняю данные в моей реляционной базе данных через пружинные данные jpa

Мой импорт:

import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

1 Ответ

0 голосов
/ 07 февраля 2019

Это потому, что вы вызываете метод @Transactional из одного и того же компонента.

@Transactional работает только для методов, вызванных для прокси, созданных Spring.Это означает, что когда вы создаете @Service или другой компонент, метод, вызываемый извне, будет транзакционным.Если вызывается из bean-компонента, ничего не произойдет, поскольку он не проходит через прокси-объект.

Самое простое решение - переместить метод в другой @Service или bean-компонент.Если вы действительно хотите сохранить его в том же компоненте, то вам нужно вызвать его, чтобы он был обернут в прокси с помощью Spring AOP.Вы можете сделать это следующим образом:

private YourClass self;

@Autowired
private ApplicationContext applicationContext;

@PostConstruct
public void postContruct(){
    self = applicationContext.getBean(YourClass.class);
}

Тогда вызов метода self приведет к открытию транзакции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...