@Transactional
一、目的:了解事物注解,会在什么情况下失效。
二、前提:
了解事物:事物是系统管理中不可缺少的一部分,Spring 提供了较好的事物管理机制,主要分为:
1,编程式事务:简单说就是手动实现事物,需要添加代码,麻烦侵入,不常用。
try{
//to do something
transactionManager.commit(status);
}catch(Exception e){
transactionManager.rollback(status);
throw new InvoiceApplyException("异常");
}
2,声明式事务:基于 AOP ,将业务与事物处理解耦,使用较多,使用方式大致两种:基于 TX 的 AOP 的 xml 配置文件方式;基于注解 @Transactional。
这里提一下关键问题:
Spring 的 AOP 机制,默认是基于 JDK 的动态代理来实现,也可以设置基于 CGLib 动态代理实现。JDK 动态代理:通过继承和被代理类,相同的 Interface 来实现对原有方法的调用和增强。
CGLib 动态代理:通过继承被代理类的方式,来实现对原有方法的调用和增强。
三,限制
通过上述描述,可以看出,Spring 的事物管理机制,依赖于 JDK 的动态代理(也可以是 CGLib),那么在这个大前提下,事物注解的使用禁忌如下:
- 使用方式:可以作用在:接口、类、类方法。但是,不建议标注在接口上。原因是配置 CGLib 动态代理时,很明显会失效。
- 只能注解在 public 方法上。private protected 不行。
- 不能将注解,标注在内部调用的方法上。必须注解在外部调用的方法上。不带注解的方法 a,调用带有注解的方法 b ,事物不会生效。为什么呢?还是因为 AOP 代理,只有当前事物方法被当前类以外的代码调用时,才会由 Spring 生成的代理对象来管理。