一、注解配置声明式事务
除了基于XML的事务配置之外,Spring还提供了基于注解的事务配置,即通过@Transaction对需要事务增强的Bean接口实现类或方法进行标注,在容器中配置基于注解的事务增强驱动,即可启用基于注解的声明式事务。
使用@Transaction 注解
顺着上面讲的,使用@Transaction对基于 aop /tx 命名空间的事务配置进行改造,比较两者的差异:
因为注解本身具有一组普适性的默认事务属性,所以往往只要为需要事务处理的业务类添加一个@Transaction注解就完成了业务类事务属性的配置。
当然,注解只是提供元数据,它本身并不能完成事务切面织入的功能。因此,还需要在Spring配件文件通过Spring 容器对标注@Transaction的Bean进行加工处理,如代码:
默认情况下,<tx:annotation-driven>会自动使用名称为“transactionManager”的事务管理器,所以如果用户的事务管理器id为“transactionManager”,可以进一步将 ① 处的配置简化为<tx:annotation-driven/>。
<tx:annotation-driven> 还有另外两个属性:
1、proxy-target-class:可选项,默认值为false,如果为true,Spring 将通过创建子类来代理业务类,如果为false,则使用基于接口的代理。如果使用子类代理,则需要在类路径中添加CGLib.jar 类库。
2、order:如果业务类除事务切面外,还需要织入其他的切面,则通过该属性可以控制事务切面在目标连接点的织入顺序。默认值:proxy。
关于@Transaction 的属性
基于@Transaction注解的配置和基于XML的配置方式一样,也拥有一组普适性很强的默认事务属性,用户往往直接使用这些默认的属性就可以了。
- 事务传播行为:PROPAGATION_REQUIRED;
- 事务隔离级别:ISOLATION_DEFAULT;
- 读写事务属性:读/写事务。
- 超时时间:依赖于底层的事务系统的默认值。
- 回滚设置:任何运行期异常引发回滚,任何检查性异常不会引发回滚。
因为这些默认设置在大多数情况下都是适用的,一般不需要手工设置事务注解的属性,见下图,当然,Spring允许通过手工设置属性值覆盖默认值。
@Transaction 注解可以被应用与接口定义和接口方法、类定义和类的public 方法上。但Spring 建议在业务实现类上使用@Transaction 注解,当然也可以在业务接口上使用@Transaction 注解。 但这样会留下一些容易被忽视的隐患。因为注解不能被继承,所以业务接口中标注的@Transaction 注解不会被实现业务类继承,如果通过以下的配置启用子类代理:
<!-- 启用事务注解 -->
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
业务类不会添加事务增强,照样工作在非事务的环境下。例如,如果使用子类代理,假设用户为IViewSpace接口标注了@Transaction 注解,其实现类ViewSpaceImpl 依旧不会启用事务机制。
因此,Spring建议在具体业务类上使用@Transaction 注解。这样,不管<tx:annotation-driven> 将 proxy-target-class 属性值配置为true 还是false ,业务类都会启用事务机制。
在方法处使用注解:
方法处的注解会覆盖类定义处的注解,如:
使用不同的事务管理器
在不同的方法上使用不同的事务管理器,可以在xml文件中配置这些个不同的事务管理器。
如:
XML文件中配置的事务管理器,如图: