При каких исключениях Spring откатывает транзакцию?
- Откатывается ли транзакция при checked exception?
- Что делает rollbackFor?
По умолчанию Spring откатывает транзакцию при непроверяемых исключениях (RuntimeException и Error) и коммитит при проверяемых (checked, например IOException). Изменить: rollbackFor = Exception.class или noRollbackFor. Если исключение поймано внутри метода и не выброшено наружу, прокси его не видит — транзакция закоммитится. Если внутренний транзакционный метод пометил транзакцию на откат, а внешний поймал исключение, при коммите будет UnexpectedRollbackException.
- Проглоченное исключение — частая причина «почему данные сохранились наполовину»
- Свои бизнес-исключения обычно наследуют от RuntimeException
- Явно откатить без исключения — TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()
А ещё Откат касается только базы: отправленное письмо или HTTP-вызов не откатятся
Подробно
@Transactional
public void importFile(Path p) throws IOException {
repo.save(header);
parse(p); // IOException — транзакция ЗАКОММИТИТСЯ
}
@Transactional(rollbackFor = Exception.class)
public void importSafe(Path p) throws IOException { ... }Что хотят услышать
- Откат при RuntimeException, коммит при checked.
- rollbackFor и noRollbackFor.
- Пойманное исключение не откатывает.
- Внешние действия не откатываются.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✓По умолчанию — при RuntimeException и Error; checked-исключения коммитят, если не задан rollbackFor
- ✗При любом исключении, включая checked: IOException откатывает так же, как RuntimeException
- ✗Только при checked-исключениях, а RuntimeException по умолчанию транзакцию коммитит
- ✗При любом исключении, даже пойманном и обработанном внутри самого метода
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.