Этот вопрос проверяет понимание применения транзакций в сервисном слое для обеспечения целостности данных при выполнении нескольких операций с базой данных.
Транзакции — это механизм, который группирует несколько операций с базой данных в одну логическую единицу работы. Основная цель — обеспечить целостность данных, следуя принципам ACID (атомарность, согласованность, изоляция, долговечность).
Рассмотрим сервис для перевода денег между банковскими счетами. Без транзакции, если второй update завершится ошибкой, деньги будут списаны, но не зачислены.
@Service
public class TransferService {
@Autowired
private AccountRepository accountRepository;
@Transactional
public void transferMoney(Long fromId, Long toId, BigDecimal amount) {
Account fromAccount = accountRepository.findById(fromId).orElseThrow();
Account toAccount = accountRepository.findById(toId).orElseThrow();
if (fromAccount.getBalance().compareTo(amount) < 0) {
throw new InsufficientFundsException();
}
// Две операции должны быть атомарными
fromAccount.setBalance(fromAccount.getBalance().subtract(amount));
toAccount.setBalance(toAccount.getBalance().add(amount));
accountRepository.save(fromAccount);
accountRepository.save(toAccount);
// Если здесь произойдёт исключение, транзакция откатит оба изменения
}
}В современных веб-приложениях транзакции обычно управляются на уровне сервиса с помощью аннотаций (как @Transactional в Spring) или явного управления сессией. Это позволяет отделить бизнес-логику от инфраструктурных деталей. Транзакции также полезны при работе с распределёнными системами, где могут потребоваться паттерны вроде Saga.
Вывод: Используйте транзакции в сервисном слое для сложных бизнес-операций, которые изменяют несколько записей в базе данных, чтобы гарантировать целостность данных и избежать частичных обновлений.