Вчера долго разбирал одну проблему в бизнес логике - внутри транзакции происходила попытка отправить письмо. @Transactional
public void method() {
try {
//logic
} catch (Exception e) {
// report with a new transaction
}
}
Попытка эта фейлилась, чем запускала ветку отправки отчета об этом фейле, и в отчетный метод передавался id сущности в процессе обработки которой произошел сбой. Проблема в томб что отчетный механизм начинал новую транзакцию, и мы попадали в очень типичный дедлок, когда двум разным коннектам к БД нужна стала блокировка на одну запись.
Как сделать правильно:public void method() {
try {
// call transactional method
} catch (Exception e) {
// call report with a new transaction }
}
И вообще любые транзакции надо делать максимально легкими и пытаться избегать любых внешних вызовов, иначе на консистентность данных начинают влиять внешние сервисы, а это очень сложно разгребать.
>>Click here to continue<<