@Transactional не работает в private-методах?В Spring
@Transactional работает через прокси. Это значит, что Spring оборачивает бин в обёртку, которая и управляет транзакцией. Но есть важный нюанс:📌 Прокси перехватывает только ВНЕШНИЕ вызовы метода.
Если вы вызываете
@Transactional-метод изнутри того же класса, транзакция не начнётся.Пример:
@Service
public class UserService {
public void createUser() {
// вызов внутреннего метода — транзакция не активируется
saveUser();
}
@Transactional
private void saveUser() {
// НЕ будет работать как транзакционный
}
}
💡 Даже если вы сделаете метод
public, но вызов будет из того же класса — эффект тот же: Spring-прокси его не "перехватит".⚠️ Аннотация
@Transactional не работает на private-методах вообще. Прокси просто не может их подменить.✅ Правильный подход:
Вынесите транзакционный метод в отдельный бин:
@Service
public class UserSaver {
@Transactional
public void saveUser() {
// теперь работает!
}
}
И используйте его из другого бина:
@Service
public class UserService {
private final UserSaver userSaver;
public UserService(UserSaver userSaver) {
this.userSaver = userSaver;
}
public void createUser() {
userSaver.saveUser(); // транзакция начнётся
}
}
📌 Или используйте аспектно-ориентированную реализацию с
@EnableAspectJAutoProxy(exposeProxy = true) + AopContext.currentProxy(), но это уже хардкор.👉 @java_geek