Ответ
Propagation.NESTED — это механизм распространения транзакций в Spring, который создает вложенную транзакцию (nested transaction) внутри существующей. Она использует точки сохранения (savepoints) базы данных, что позволяет выполнить частичный откат.
Ключевое поведение:
- Если внешняя транзакция откатывается, откатывается и вся вложенная.
- Если вложенная транзакция откатывается (и исключение перехвачено), внешняя транзакция может продолжить работу с точки сохранения, созданной до начала вложенной.
Важные ограничения:
- Работает только с JDBC-драйверами, поддерживающими savepoints (например, PostgreSQL, H2, MySQL с InnoDB).
- Не работает с JTA-менеджерами транзакций (JTA).
Пример использования:
@Service
public class OrderService {
@Transactional(propagation = Propagation.REQUIRED)
public void processOrder(Order order) {
// Основная логика заказа
saveOrder(order);
try {
processPayment(order); // Вложенная транзакция
} catch (PaymentFailedException e) {
// Откат ТОЛЬКО операций payment, order сохраняется
log.error("Payment failed, order kept", e);
}
// Внешняя транзакция продолжается
}
@Transactional(propagation = Propagation.NESTED)
public void processPayment(Order order) {
// Логика платежа, которая может откатиться независимо
paymentGateway.charge(order);
}
}
Сравнение с REQUIRES_NEW:
- REQUIRES_NEW: Создает полностью новую, независимую физическую транзакцию. Приостанавливает внешнюю.
- NESTED: Использует точку сохранения в рамках одной физической транзакции. Более легковесна, но зависит от поддержки СУБД.