Ответ
Аннотация @Transactional декларативно управляет границами транзакций в Spring. Она применяется на уровне метода или класса.
Базовый пример:
@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(); // RuntimeException вызовет rollback
}
fromAccount.debit(amount);
toAccount.credit(amount);
// Сохранение не требуется явно, если используется контекст persistence с flush-mode AUTO (по умолчанию в @Transactional)
}
}
Ключевые атрибуты для настройки:
propagation: Определяет поведение транзакции относительно существующего контекста (например,REQUIRED,REQUIRES_NEW).isolation: Уровень изоляции (например,READ_COMMITTED,SERIALIZABLE).rollbackFor/noRollbackFor: Какие исключения вызывают или не вызывают откат.readOnly: Флаг только для чтения (оптимизация дляtrue).timeout: Таймаут транзакции в секундах.
Важно: @Transactional работает через AOP-прокси, поэтому вызовы методов внутри одного класса не будут перехвачены прокси. По умолчанию откат происходит только при непроверяемых исключениях (RuntimeException и его наследниках).