🧠 Частая ловушка при работе с @Transactional в Spring



Сейчас покажу вам один распространённый анти-паттерн, который легко пропустить — вызов транзакционного метода внутри того же класса.

📌 Пример:

@Service
public class UserService {

@Transactional
public void registerUser(UserDto dto) {
saveUser(dto);
}

@Transactional
public void saveUser(UserDto dto) {
// сохранение пользователя
}
}


💥 Проблема:
Spring не применит транзакцию к saveUser(), потому что вызов происходит внутри одного и того же бина — минуя прокси.

Spring AOP работает через прокси, и @Transactional "срабатывает", только если метод вызывается извне, через прокси-объект.

⚠️ Это может привести к очень странным багам: вы думаете, что транзакция есть, а её нет.

💡 Как исправить:

1. Вынести метод в отдельный бин:

@Service
public class UserSaver {
@Transactional
public void save(UserDto dto) {
// сохраняем
}
}

@Service
public class UserService {
private final UserSaver saver;

public UserService(UserSaver saver) {
this.saver = saver;
}

public void registerUser(UserDto dto) {
saver.save(dto);
}
}


2. Или использовать TransactionTemplate вручную.

✅ Всегда проверяйте, как вызываются методы с @Transactional. Особенно при рефакторинге!

👉 @BookJava
Просмотры: 583
Открыть в MAX Сообщить о неточности

Репосты публикации

Публикация канала

Сообщить о неточности

Опишите, что нужно исправить. Если есть источник, добавьте ссылку.

Вы покидаете datool.ru

Ссылка ведёт на внешний сайт. datool.ru не отвечает за его содержимое — проверьте адрес, прежде чем вводить пароли или платёжные данные.

Переход через 10 с

Перейти