Spring4.2—— Spring的事务控制

 1、传统事务控制存在的问题:

  持久化技术不同,事务控制的API也会不同,会导致事务控制代码也会随之改变。程序将Service层与DAO分离,目的就是为让Service只负责业务变化,DAO专门负责持久化技术的变化。事务控制代码需要放在Service层完成,持久化技术的改变,必然导致Service组件也要随之修改。

2、Spring的事务控制

(1)特征:Spring的事务管理不需要与任何特定的事务API耦合(面向PlatformTransactionManager)。对不同的持久层访问技术,编程式事务提供一致的事务管理,通过模块化的一致性操作管理事务。
(2)优势:
   ①不需要硬编码的方式写事务
   ②让业务逻辑API与具体的事务逻辑分离
   ③没有提供实际的事务支持,只是对底层的事务包装,所以能自由切换底层的事务

(3)事务控制中的策略模式:当程序要完成某个功能时(事务),但实现该功能可能有多个实现算法,目前不希望或不确定要采用哪种实现算法,此时可考虑使用策略模式。

      策略模式由如下部分组成:

   ① 一个策略接口,该策略接口只定义实现功能所需的方法,不提供实现。
        PlatformTransactionManager:事务控制的策略接口。只定义事务控制的3个方法。

   ②N个策略实现类:为不同的算法提供对应的策略实现类。
        DataSourceTransactionManager:采用JDBC持久化技术,用该事务策略实现类。
        HibernateTransactionManager:采用Hibernate持久化技术,用该事务策略实现类。
        JpaTransactionManager:采用JPA持久化技术,用该事务策略实现类。
        JtaTransactionManager:使用JTA全局事务,用该事务策略实现类
        WebLogicJtaTransactionManager, WebSphereUowTransactionManager

   ③Context类:负责为程序“智能”地选择一个策略实现类。 ——其实要靠配置。
        ApplicationContext

      TransactionDefinition:代表事务定义。用于指定事务相关属性。(隔离级别传播性超时是否只读

(4)Spring的事务控制有两种方式:

   ①编程式事务。需要自己来写Java代码控制事务。面向PlatformTransactionManager编程、还可结合AOP。

         a.增加aspect类

public class TxAspect {

	private PlatformTransactionManager transactionManager;
	public void setTransactionManager(PlatformTransactionManager transactionManager)
	{
		this.transactionManager = transactionManager;
	}
	// 定义一个Around Advice
	public Object tx(ProceedingJoinPoint jp){
		// 创建默认的事务定义(永不超时) ——是不好的。
		DefaultTransactionDefinition td = new DefaultTransactionDefinition();
		// 开启事务,  需要传入TransactionDefinition对象,用于指定事务相关的属性(隔离、传播、超时、只读)
		TransactionStatus status = transactionManager.getTransaction(td);
		Object rvt = null;
		try {
			rvt = jp.proceed(); // 直接使用原来的参数调用目标方法	
			transactionManager.commit(status);// 提交事务
		} catch (Throwable e) {
			e.printStackTrace();
			transactionManager.rollback(status);// 回滚事务
		}
		return rvt;
	}
}
        b.在appCtx中配置:

	<!-- 此处就是配置事务策略的实现类,也就是为PlatformTransactionManager指定实现类 -->
	<bean id="transactionManager"
		class="org.springframework.orm.hibernate5.HibernateTransactionManager"
		p:sessionFactory-ref="sessionFactory" />
	
	<bean id="txAspect" class="aspect.TxAspect"
		p:transactionManager-ref = "transactionManager"
	/>
	<aop:config>
		<aop:pointcut expression="execution(* service.impl.*.*(..))"
			id="pc" />	 
		<!-- 将txAspect当成Aspect使用 -->
		<aop:aspect ref="txAspect">
			<aop:around method="tx" pointcut-ref="pc"/>
		</aop:aspect>
	</aop:config>

   ②声明式事务。不需要自己写Java代码,只要用XML或注解配置即可。

      a.在appCtx中配置:

      注意:需要导入tx命名空间

<!-- 以下为事务配置 -->
	<!-- 为PlatformTransactionManager事务策略接口指定实现类,
		  ApplicationContext就会为我们选择该事务策略实现类
	  -->
	<bean id="transactionManager"
	 class="org.springframework.orm.hibernate5.HibernateTransactionManager"
		p:sessionFactory-ref="sessionFactory"/>

	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<!-- 下面就是用于定义事务属性  -->
		<tx:attributes>
			<!-- 访问get方法属性配置 -->
			<tx:method name="get*" read-only="true" timeout="8"/>
			<!-- 访问其他方法属性配置 -->
			<tx:method name="*" timeout="5"/>
		</tx:attributes>
	</tx:advice>

	<aop:config>
		<!-- 为切入点表达式起个名字 -->
		<aop:pointcut expression="execution(* service.impl.*.*(..))"
			id="pc" />
		<!-- 指定将指定的Advice,织入到切入点表达式所匹配的方法。 -->
		<aop:advisor advice-ref="txAdvice" pointcut-ref="pc" />
	</aop:config>      

其余代码可参考: Spring3.3节中s2sh整合

3、注解配置事务可参考:Spring 使用注解方式进行事务管理

猜你喜欢

转载自blog.csdn.net/ack_finding/article/details/78963009