Что делает @Transactional в Spring и где его ставить?
- Зачем нужен @Transactional?
- Что такое readOnly = true?
@Transactional на методе бина означает: перед вызовом открыть транзакцию, после успешного выхода — закоммитить, при исключении — откатить. Все операции с базой внутри метода выполняются атомарно: либо все, либо ни одна. Ставят на методы сервисного слоя, где собирается бизнес-операция из нескольких действий («списать со счёта и записать платёж»), а не на контроллеры. readOnly = true — для чтения: подсказка драйверу и Hibernate (без отслеживания изменений).
- Работает через прокси — только для public-методов, вызванных извне бина
- Транзакция держит соединение с базой — не делать внутри долгих HTTP-вызовов
- Ленивая загрузка JPA работает внутри транзакции
А ещё Транзакция должна быть короткой: только работа с базой
Подробно
@Service
class TransferService {
@Transactional
public void transfer(long from, long to, BigDecimal amount) {
accounts.debit(from, amount);
accounts.credit(to, amount); // ошибка здесь откатит debit
}
@Transactional(readOnly = true)
public List<Account> list() { return accounts.findAll(); }
}Что хотят услышать
- Коммит и откат по результату метода.
- Атомарность нескольких операций.
- Сервисный слой, readOnly.
- Ограничения прокси и длительность.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✗Ставят на контроллеры, чтобы одна транзакция покрывала весь запрос вместе с HTTP-вызовами
- ✓Делает операции с базой атомарными: коммит при успехе, откат при исключении; ставят на сервисы
- ✗Работает на любых методах, включая private, потому что Spring встраивается прямо в байткод класса
- ✗readOnly = true запрещает чтение данных
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.