Transactional失效场景
5 Transactional失效场景
1 方法非 public 修饰
原因
Spring 的 @Transactional 注解只能作用于 public 方法。如果方法是非 public 的(如 private、protected 或包级私有),事务不会生效。
@Transactional
private void saveUser(User user) {
// 业务逻辑
}
//改为public修饰
@Transactional
public void saveUser(User user) {
// 业务逻辑
}
2 类内部方法调用。
原因
Spring 的事务管理是基于代理模式实现的。如果通过类内部方法调用事务方法,代理不会生效,事务也不会生效。
场景:
@Service
public class UserService {
public void saveUser(User user) {
save(user); // 内部调用
}
@Transactional
private void save(User user) {
// 业务逻辑
}
}
解决方法1 将事务方法移到另一个类中:
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public void saveUser(User user) {
userRepository.save(user);
}
}
@Repository
public class UserRepository {
@Transactional
public void save(User user) {
// 业务逻辑
}
}
解决方法2 使用AopContext.currentProxy() 获取当前代理对象
@Service
public class UserService {
public void saveUser(User user) {
//使用AopContext.currentProxy() 获取当前代理对象
((UserService) AopContext.currentProxy()).save(user);
}
@Transactional
public void save(User user) {
// 业务逻辑
}
}
3 异常未抛出或被捕获。
原因:
默认情况下,@Transactional 只在抛出 RuntimeException 或 Error 时回滚事务。如果异常被捕获且未重新抛出,事务不会回滚。
@Transactional
public void saveUser(User user) {
try {
// 业务逻辑
} catch (Exception e) {
// 捕获异常
}
}
解决方法
@Transactional
public void saveUser(User user) {
try {
// 业务逻辑
} catch (Exception e) {
throw new RuntimeException(e); // 重新抛出异常
}
}

浙公网安备 33010602011771号