Новое Распределяем каналы MAX по категориям и территориям. Читать новость

Spring: граница транзакции должна охватывать бизнес-операцию целиком.



Например, перевод денег – это списание с одного счёта и зачисление на другой. Разместите оба действия в методе сервиса:
@Service
@RequiredArgsConstructor
public class TransferService {
    private final AccountRepository accounts;

    @Transactional
    public void transfer(Long fromId, Long toId,
                         BigDecimal amount) {
        var from = accounts.findById(fromId).orElseThrow();
        var to = accounts.findById(toId).orElseThrow();

        from.withdraw(amount);
        to.deposit(amount);
    }
}
Оба изменения фиксируются вместе. Если при зачислении возникнет исключение, вызывающее откат, списание тоже отменится.

Контроллеру остаётся проверить входные данные и вызвать сервис. Бизнес-правила находятся рядом с операцией, которую защищает транзакция.

Два нюанса:

- По умолчанию Spring откатывает транзакцию при `RuntimeException` и `Error`. Для checked exceptions можно настроить rollbackFor.
- В стандартном proxy-режиме вызов метода через `this` не активирует `@Transactional`.

Транзакция также не заменяет защиту от конкурентных изменений: для денежных операций отдельно продумайте блокировки или контроль версий.
Просмотры: 48
Открыть в MAX Сообщить о неточности

Сообщить о неточности

Опишите, что нужно исправить. Если есть источник, добавьте ссылку.

Вы покидаете datool.ru

Ссылка ведёт на внешний сайт. datool.ru не отвечает за его содержимое — проверьте адрес, прежде чем вводить пароли или платёжные данные.

Переход через 10 с

Перейти