Ответ
Параметр propagation определяет поведение транзакции при её вызове из другого транзакционного метода. Он управляет тем, как должна вести себя новая транзакция в контексте существующей.
Основные значения:
REQUIRED(по умолчанию): Использует существующую транзакцию, если она есть, или создаёт новую.REQUIRES_NEW: Всегда создаёт новую транзакцию, приостанавливая текущую, если она существует.SUPPORTS: Выполняется в транзакции, если она есть, иначе — без транзакции.NOT_SUPPORTED: Выполняет метод без транзакции, приостанавливая текущую, если она есть.MANDATORY: Требует активной транзакции, иначе выбрасывает исключение.NEVER: Требует отсутствия транзакции, иначе выбрасывает исключение.NESTED: Создаёт вложенную транзакцию внутри существующей (работает, если БД поддерживает savepoints).
Пример использования REQUIRES_NEW:
@Service
public class OrderService {
@Transactional(propagation = Propagation.REQUIRED)
public void placeOrder(Order order) {
// Основная логика заказа
saveOrder(order);
// Логирование должно быть независимо от отката основной транзакции
logAuditEvent(order);
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void logAuditEvent(Order order) {
// Эта запись в лог-таблицу будет сохранена,
// даже если основная транзакция placeOrder откатится
auditRepository.save(new AuditEvent("Order placed", order.getId()));
}
}
Почему это важно: Правильный выбор propagation предотвращает непредсказуемое поведение (например, нежелательный откат логирования или блокировку данных) и обеспечивает атомарность операций на нужном уровне.