Spring аннотация @Transactional при использовании блока try catch
Я просто хочу знать, что если мы поймаем исключение в методе, аннотируемом аннотацией @Transactional, то он откатится, если произойдет какое-либо исключение?
Thanx заранее
@Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor=Throwable.class)
@Scheduled(cron = "0 0 0 31 3 ?")
public void yearEndProcess(){
Company company = null;
try{
--try block--
}
catch(Throwable throwable){
--catch block --
}
Ответы
Ответ 1
например
class A{
@Transactional
public Result doStuff(){
Result res = null;
try {
// do stuff
} catch (Exception e) {
}
return res ;
}
}
Если в методе doStuff
есть исключение, транзакция не откатна.
To rollback the exception programmatically
, мы можем сделать что-то вроде ниже.
декларативный подход
@Transactional(rollbackFor={MyException1.class, MyException2.class, ....})
public Result doStuff(){
...
}
программный откат
вам нужно вызвать его из TransactionAspectSupport
.
public Result doStuff(){
try {
// business logic...
} catch (Exception ex) {
// trigger rollback programmatically
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
}
You are strongly encouraged to use the `declarative approach` to `rollback` if at all possible.
`Programmatic rollback` is available should only be used if you absolutely need it.
Ответ 2
вы бы хотели прочитать this
Интегрированное управление транзакциями. Вы можете обернуть ваш ORM-код с помощью декларативного, ориентированного на аспектное программирование (AOP) метода перехватчика стиля либо через аннотацию @Transactional, либо путем явной настройки рекомендации AOP транзакции в файле конфигурации XML. В обоих случаях для вас обрабатываются семантика транзакций и обработка исключений (откат и т.д.). Как описано ниже, в разделе Управление ресурсами и транзакциями вы также можете менять различные менеджеры транзакций, не затрагивая ваш код, связанный с ORM. Например, вы можете поменять местами между локальными транзакциями и JTA с одинаковыми полными службами (такими как декларативные транзакции), доступными в обоих сценариях. Кроме того, JDBC-связанный код может полностью интегрировать транзакцию с кодом, который вы используете для ORM. Это полезно для доступа к данным, которое не подходит для ORM, например, пакетной обработки и потоковой передачи BLOB, которым все еще необходимо обмениваться общими транзакциями с операциями ORM.
Ответ 3
Из spring документации по документации
Spring рекомендует только аннотировать конкретные классы (и методы конкретных классов)
с аннотацией @Transactional, в отличие от аннотирующих интерфейсов. Вы, безусловно, можете
поместите аннотацию @Transactional на интерфейс (или метод интерфейса), но это работает
только так, как вы ожидаете, если вы используете прокси-серверы на основе интерфейса. Тот факт, что Java
аннотации не наследуются от интерфейсов, означает, что если вы используете прокси-классы на основе классов
(proxy-target- class= "true" ) или аспектом ткачества (mode = "aspectj" ), затем
параметры транзакции не распознаются инфраструктурой проксирования и переплетения, а
объект не будет завернут в транзакционный прокси, что было бы явно плохо.
В режиме прокси (который по умолчанию), только внешние вызовы методов, поступающие через прокси-сервер,
перехвачены. Это означает, что self-invocation, по сути, метод в вызове целевого объекта
другой метод целевого объекта, не приведет к фактической транзакции во время выполнения, даже если
вызывается метод @Transactional.
Затем с @Transaction поведение по умолчанию заключается в том, что любое исключение RuntimeException вызывает откат, а в любом исключенном исключении нет. Затем ваш транзакционный откат для всех RuntimeException a для отмеченного Exception Throwable
Ответ 4
Вы уже упоминали атрибут: rollbackFor = Throwable.class в аннотации @Transactional.
Итак, для любого вида транзакции исключения будет откат назад.