@Транзакционный откат для области видимости

#java #spring-boot #hibernate #exception #transactions

#java #весенняя загрузка #переход в спящий режим #исключение #транзакции

Вопрос:

Я использую @Transactional в своем коде и создаю пользовательское исключение для отображения сообщений об ошибках в определенном формате в пользовательском интерфейсе.

 public class MyCustomException extends RuntimeException
  

При возникновении этого исключения я все равно хочу откатить свои транзакции, так же, как и в случае возникновения любого другого исключения.

Итак, чтобы это сработало, я пишу приведенный ниже код:

 // service method called from rest controller
public List<String> getMyData() { 
    
    List<String> errors = new ArrayList();
    try {
        businessMethod();
    } catch (MyCustomException e) {
        log.error(e.getMessage);
        errors.add(e.getMessage)
    }
return errors.
}

@Transactional(rollbackFor = {MyCustomException.class, RuntimeException.class, Exception.class})
public String businessMethod() {
    // Business logic to get data that can throw MyCustomException
}
  

Мои вопросы:

  1. Если я упоминаю MyCustomException.class в rollbackFor , нужно ли мне также упоминать RuntimeException.class, Exception.class . Или все, что упоминается в rollbackFor , добавляется вместе с исключениями по умолчанию, для которых выполняется откат транзакции.

  2. Хотя я избегаю MyCustomException from businessMethod() , но я улавливаю это в вызывающем методе getMyData() . Я предполагаю, что транзакция будет откатана в случае исключения, правильно?

Комментарии:

1. Я думаю, что вы неправильно используете транзакционную аннотацию в данном примере. Правильным способом должно быть вызывать businessMethod в некотором компоненте spring, а не напрямую.

Ответ №1:

  1. Транзакция будет откатана на любой RuntimeException , поэтому нет необходимости объявлять свой собственный MyException.class в rollbackFor разделе, поскольку ваш MyException расширяется RuntimeException . Если вы объявите, Exception.class откат будет выполнен для любого исключения. Но в вашем случае вам это вообще не нужно rollbackFor .

  2. Да, это правильно. Ваш перевод начинается и заканчивается на businessMethod() .

Комментарии:

1. Спасибо, но у меня есть сомнения в pt. 2. Я не думаю, что произойдет откат.

2. Вы пробовали это? Ожидаемым поведением должно быть то, что транзакция в вашем случае откатывается, потому что вы перехватываете свое исключение из области @Transactional.