这个是spring的声明式事务管理,基于AOP编程,是一种动态代理模式。 疑问
1.这个注解是怎么生效的? 配置了transactional注解后,spring容器初始化bean的时候,给他生成代理类,执行的时候控制事务的提交。 2.多个数据库的事务怎么办? 你需要在注解的地方指明数据源@Transactional("order")
其他注意事项
首先,事务管理只会对RuntimeException及其之类的异常回滚数据,也就是非受检异常。其他异常比如Error,是jvm错误导致的致命错误,其他Exception及其子类等受检异常,编译器会检查,需要程序人员处理掉。
其次,内部类调用@Transactional的方法,也不会有事务,只有来自外部的方法调用才会被AOP代理捕获。原因是,本质上是一个AOP,生成这个类的代理类,调用自身类的方法是不能触发。
事务传播属性,前面两个用的比较多
@Transactional(propagation=Propagation.REQUIRED)//如果有事务,那么加入事务,没有的话新创建一个
@Transactional(propagation=Propagation.SUPPORTS)//有就用事务,没有就算了
@Transactional(propagation=Propagation.NOT_SUPPORTED)//有事务也不用
@Transactional(propagation=Propagation.REQUIREDS_NEW)//不管是否存在事务,都创建一个新的事务,原来的挂起,新的执行完毕,继续执行老的事务
@Transactional(propagation=Propagation.MANDATORY)//必须在一个已有的事务中执行,否则抛出异常
@Transactional(propagation=Propagation.NEVER)//不能在一个事务中执行,就是当前必须没有事务,否则抛出异常
@Transactional(propagation=Propagation.NESTED)//如果一个活动的事务存在,则运行在一个嵌套的事务中,如果没有活动的事务,则按照REQUIRED属性执行,它使用一个单独的事务。这个书屋拥有多个回滚的保存点,内部事务的回滚不会对外部事务造成影响,它只对DataSource TransactionManager事务管理器起效。
@Transactional(propagation=Propagation.REQUIRED,readOnly=true)//只读,不能更新,删除
@Transactional(propagation=Propagation.REQUIRED,timeout=30)//超时30秒@Transactional(propagation=Propagation.REQUIRED,isolation=Isolation.DEFAULT)//数据库隔离级别
代理的选择
通过元素的 “proxy-target-class” 属性值来控制是基于接口的还是基于类的代理被创建。如果 “proxy-target-class” 属值被设置为 “true”,那么基于类的代理将起作用(这时需要CGLIB库cglib.jar在CLASSPATH中)。如果 “proxy-target-class” 属值被设置为 “false” 或者这个属性被省略,那么标准的JDK基于接口的代理将起作用。