Вопрос проверяет понимание того, когда транзакции в Spring действительно работают и как правильно выстраивать границы сервисов.
При вызове метода между разными бинами вызов проходит через прокси. В этом случае @Transactional отрабатывает корректно. Spring создаёт или присоединяет транзакцию в зависимости от настроек propagation. Именно так транзакции и должны использоваться в типовой архитектуре. Поэтому транзакционные методы обычно выносят в отдельные сервисы.
Взаимодействие между разными классами — это «правильный» сценарий работы транзакций в Spring.
Когда один бин вызывает метод другого бина:
Spring подставляет прокси вместо реального объекта
Вызов перехватывается
Транзакционная логика применяется
@Service
public class OrderService {
private final PaymentService paymentService;
public OrderService(PaymentService paymentService) {
this.paymentService = paymentService;
}
public void createOrder() {
paymentService.pay();
}
}
@Service
public class PaymentService {
@Transactional
public void pay() {
// транзакция будет создана
}
}
Поведение транзакций зависит от propagation.
REQUIRED (по умолчанию)Если транзакция уже есть — используется она
Если нет — создаётся новая
REQUIRES_NEWВсегда создаётся новая транзакция
Внешняя приостанавливается
Используются реже и для специфических сценариев.
Транзакции определяют границы бизнес-операций
Эти границы чаще всего совпадают с сервисами
Это упрощает понимание и поддержку кода
При вызове методов между разными классами транзакции в Spring работают корректно, так как вызов проходит через прокси и учитывает правила propagation.