Ответ
Нет, новая транзакция по умолчанию не откроется. Это происходит из-за особенностей реализации AOP в Spring на основе прокси-объектов.
Причина: Вызов метода methodB() внутри класса MyService — это обычный вызов Java-метода, который минует Spring-прокси. Поэтому аннотация @Transactional на methodB() игнорируется, и код выполняется в рамках существующей транзакции methodA().
Пример проблемного кода:
@Service
public class MyService {
@Transactional
public void methodA() {
// Эта транзакция активна
methodB(); // @Transactional НЕ СРАБОТАЕТ! Вызов в той же транзакции.
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void methodB() {
// Этот код всё равно выполнится в транзакции methodA
}
}
Способы заставить новую транзакцию открыться:
-
Self-injection (внедрение зависимости в самого себя):
@Service public class MyService { @Autowired private MyService self; // Ссылка на прокси-объект @Transactional public void methodA() { self.methodB(); // Вызов через прокси -> откроется новая транзакция } @Transactional(propagation = Propagation.REQUIRES_NEW) public void methodB() { // Логика в новой, независимой транзакции } } - Вынести метод в отдельный сервис и внедрить его.
- Использовать AspectJ вместо Spring AOP (режим
mode = AspectJWeaving.ENABLED), но это сложнее и требует дополнительной настройки.
Ключевой вывод: Для работы транзакционных аннотаций вызов должен проходить через Spring-прокси.