Spring事务策略是通过PlatformTransactionManager接口实现的,该接口是Spring事务策略的核心,PlatformTransactionManager接口有许多不同的实现类,底层使用不同的持久层技术,Spring会选用不同的实现类实现事务功能,这是典型的策略模式。
Spring事务依赖SpringAOP,简单来讲就是对需要开启事务的犯法进行横切处理,在原方法体前开启事务,在原方法后提交或者回滚事务。只是该AOP的adcice不用我们写,Spring内置了优秀的管理事务的advice,也就是PlatformTransactionManager的实现类。
Spring本身并不支持任何事务,它只是包装底层的事务。
开启Spirng事务3步:
- 创建事务管理器
- 配置事务管理器,生成Advice
- 将Advice与指定切入点(target)绑定
1.创建事务管理器
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:dataSource-ref="c3p0" />
属性dataSource:指定数据源
2.配置事务管理器,生成Advice
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="get*" read-only="true" timeout="8"
isolation="DEFAULT" propagation="REQUIRED"/>
<tx:method name="*" read-only="false" timeout="8"
isolation="DEFAULT" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
属性:
- name:必须属性,指定切入点的方法名,可使用通配符;
- isolation:指定事务隔离级别;
- timeout:指定事务超时;
- read-only:指定事务是否只读;
- rollback-for:指定些个异常类(全限定)会触发事务回滚;
- no-rollback-for:指定哪些异常类不会触发事务回滚,(默认情况下uncheck异常 [包括runtime异常和error] 会触发事务回滚,check异常不会触发事务回滚)
- propagation:指定事务传播行为;
3. 将Advice与指定切入点(target)绑定
利用 <aop:advisor/>
<aop:config proxy-target-class="true">
<!--配置切入点-->
<aop:pointcut id="myPointcut"
expression="execution(* com.lyx.service.PersonServiceImpl.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="myPointcut"/>
</aop:config>
注解方式配置事务
当然也可以用注解方式配置事务(准确来说是注解和xml结合):
第1不步照样在xml中配置事务管理器
第2步和第3步在xml中现在只需要一行 (也就是只需要告诉Spring用哪个事务管理器以及是否开启事务管理)
<tx:annotation-driven transaction-manager="transactionManager"/>
tips:如果报错Exception in thread “main” java.lang.ClassCastException: class com.sun.proxy.$Proxy30 cannot be cast to class com.lyx.service.PersonServiceImpl
就在tx标签中添加属性proxy-target-class=“true”
使用的注解为:@Transactional,该注解既可以修饰类也可以修饰方法,表示需要开启事务的方法。
该注解中可以指定:
- isolation:指定事务隔离级别;
- timeout:指定事务超时;
- readOnly:指定事务是否只读;
- propagation:指定事务传播行为;
- rollbackFor:指定些个异常类(全限定)会触发事务回滚;
- noRollbackFor:指定哪些异常类不会触发事务回滚,(默认情况下uncheck异常 [包括runtime异常和error] 会触发事务回滚,check异常不会触发事务回滚)
- rollbackForClassName:指定些个异常类(全限定)会触发事务回滚;
- noRollbackForClassName:指定哪些异常类不会触发事务回滚,(默认情况下uncheck异常 [包括runtime异常和error] 会触发事务回滚,check异常不会触发事务回滚)