Spring中常用的事务配置方式有2种,一种基于XML配置,一种基于注解也就是@transactional,但不是所有的地方都可以使用注解的,那么什么情况下才能正常使用注解呢?
被注解的类实例必须被Spring管理,而不能是自己new的
- 这个好理解只有被Spring管理,它才能在运行时创建代理类,配合@transactional处理事务。
- 根据目标是否实现了接口可以将代理方式分为2种,如果类有对应实现的接口,Spring默认使用基于JDK动态代理方式;如果类没有实现接口,Spring会使用是CGLIB代理方式。
注解可以标注在接口、接口方法上、类、类的方法上,类中方法必须是public
1.但在方法上的@transactional优先于类上的,也就是如果在类和方法上都标注了@transactional,方法上的会覆盖类上的
必须配置<tx:annotation-driven/>,@transactional才会被启用
<tx:annotation-driven/>指定了什么属性Spring就按照对应方式而不会自动适配
默认情况下只有RuntimeException事务才会回滚
基于@transactional配置的事务
<!-- 事务目标类 -->
<bean id="fooService" class="x.y.service.DefaultFooService"/>
<!-- 启用基于注释的事务行为配置 -->
<tx:annotation-driven transaction-manager="txManager"/>
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
基于xml配置的事务
<!-- 事务目标类 -->
<bean id="fooService" class="x.y.service.DefaultFooService"/>
<!-- 事务advice -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<!-- 以get开头的方法使用只读事务 -->
<tx:method name="get*" read-only="true"/>
<!-- 其他方法使用默认事务,可读写,RuntimeException回滚 -->
<tx:method name=""/>
</tx:attributes>
</tx:advice>
<aop:config>
<!-- AspectJ 切面 -->
<aop:pointcut id="fooServiceOperation" expression="execution( x.y.service.FooService.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="fooServiceOperation"/>
</aop:config>
<!-- 事务管理 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
网友评论