文章目录
- 警惕@Transactional 的坑
-
- 标记了@Transactional的private方法——不生效
- 本类中的方法调用本类中@Transactional方法——不生效
- 代码中手动处理了异常——不生效
- 即使抛出异常,也有可能不生效
写在前面
Spring 针对 Java Transaction API (JTA)、JDBC、Hibernate 和 Java Persistence API (JPA) 等事务 API,实现了一致的编程模型,而 Spring 的声明式事务功能更是提供了极其方便的事务配置方式,配合 Spring Boot 的自动配置,大多数 Spring Boot 项目只需要在方法上标记 @Transactional 注解,即可一键开启方法的事务性配置。
在使用 @Transactional 注解开启声明式事务时, 第一个最容易忽略的问题是,很可能事务并没有生效。
而使用@Transactional 注解开启声明式事务时,不光需要注意其有没有生效,其他的坑也非常多,在这里列举一下以示警惕。
警惕@Transactional 的坑
标记了@Transactional的private方法——不生效
Controller类调用UserService的createUserPrivate方法时,由于createUserPrivate方法时private的,即使加上了@Transactional,声明式事务也不会生效。
除非特殊配置(比如使用 AspectJ 静态织入实现 AOP),否则只有定义在 public 方法上的 @Transactional 才能生效。
原因是,Spring 默认通过动态代理的方式实现 AOP,对目标方法进行增强,private 方法无法代理到,Spring 自然也无法动态增强事务处理逻辑。
@Service
@Slf4j
public class UserService {
@Autowired
private UserRepository userRepository;
//标记了@Transactional的private方法
@Transactional
private void createUserPrivate(UserEntity entity) {
userRepository.save(entity);
if (ent