spring事务管理

 一、要弄清spring是如何进行事务管理的,首先来看两个接口:

1. TransactionDefinition   它包含了一些事务属性的定义(传播类型等)

 

public interface TransactionDefinition {

//....省略部分代码

 

//定义了7种事务的传播类型

  int PROPAGATION_REQUIRED = 0;

  int PROPAGATION_SUPPORTS = 1;

  int PROPAGATION_MANDATORY = 2;

  int PROPAGATION_REQUIRES_NEW = 3;

  int PROPAGATION_NOT_SUPPORTED = 4;

  int PROPAGATION_NEVER = 5;

  int PROPAGATION_NESTED = 6;

 

  //获取事务的传播类型
  int getPropagationBehavior(); 

 

}

  

2. PlatformTransactionManager  事务管理器接口;真正的事务管理就是由这个接口的实现类来完成的。

public interface PlatformTransactionManager {

    //通过事务的定义,来获取一个事务的当前状态

    TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;

    // 依照事务的状态来完成提交

    void commit(TransactionStatus status) throws TransactionException;

   // 回滚

    void rollback(TransactionStatus status) throws TransactionException;

}

  

二、事务管理的实现

  1.  spring 的事务管理分为两种方式:编程式和声明式;

    <1> 编程式:使用硬编码的方式来完成事务操作。在sping里面,又有两种方式来完成编程式事务:

    a.使用 PlatformTransactionManager  接口

  

 DefaultTransactionDefinition  dtd = new DefaultTransactionDefinition();//创建事务
dtd.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);//设置事务传播类别
TransactionStatus  ts =  transactionManager.getTransaction(dtd);//获取事务状态
 try{
	userStepMappingDao.add(us);//保存对象US
	stepCategoryDao.add(usd);//保存对象USD
	transactionManager.commit(ts);//提交
   }catch(Exception e){
	transactionManager.rollback(ts);//回滚
		 }	

 

    b.使用TransactionTemplate;看一下源码

public class TransactionTemplate extends DefaultTransactionDefinition
		implements TransactionOperations, InitializingBean {
    //可以看到, TransactionTemplate继承自DefaultTransactionDefinition

    //内部还是使用了PlatformTransactionManager接口

private PlatformTransactionManager transactionManager;

  

   //看一下主要的方法:

   

public <T> T execute(TransactionCallback<T> action)
			throws TransactionException {
		// 如果当前的事务管理器实现了CallbackPreferringPlatformTransactionManager接口
		// ,则直接调查用接口的execute方法,这部分我们以后再看
		if (this.transactionManager instanceof CallbackPreferringPlatformTransactionManager) {
			return ((CallbackPreferringPlatformTransactionManager) this.transactionManager)
					.execute(this, action);
		} else {

			// 由于继承自 DefaultTransactionDefinition,直接获取事务状态
			TransactionStatus status = this.transactionManager
					.getTransaction(this);
			T result;
			try {

				// 这里action.doInTransaction(status);是我们自己的应用代码
				// (这里考虑是否通过反射来调用DAO里面的方法)
				result = action.doInTransaction(status);
			} catch (RuntimeException ex) {
				// Transactional code threw application exception -> rollback

				// point A:
				rollbackOnException(status, ex);
				throw ex;
			} catch (Error err) {
				// Transactional code threw error -> rollback

				// point B:
				rollbackOnException(status, err);
				throw err;
			} catch (Exception ex) {
				// Transactional code threw unexpected exception -> rollback

				// point C:
				rollbackOnException(status, ex);
				throw new UndeclaredThrowableException(ex,
						"TransactionCallback threw undeclared checked exception");
			}
			// 提交
			this.transactionManager.commit(status);
			return result;
		}
	}

 

 可以看到,最终还是调用ransactionManager的rollback()方法。所以TransactionTemplate只是对PlatformTransactionManager作了一个内部调用而已。

 

 

<2>声明式:这也是最常用的方法,因这这种方法不会发生任何的代码侵入;

a. 使用org.springframework.transaction.interceptor.TransactionProxyFactoryBean进行手动代理

<bean id="baseTxProxy" abstract="true"
		class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
		<property name="transactionManager">
			<ref bean="transactionManager" /> //注入事务管理器
		</property>
		<!-- 这里通过target属性为某个接口加上事务,通过方法名来匹配 -->
		<property name="target">
			<ref  bean="testTran" />//需要加事务的service
		</property>
		<property name="transactionAttributes">
			<props>
				<prop key="add*">PROPAGATION_REQUIRED</prop> 
				<prop key="update*">PROPAGATION_REQUIRED</prop>
				<prop key="delete*">PROPAGATION_REQUIRED</prop>
				<prop key="save*">PROPAGATION_REQUIRED</prop>
				<prop key="remove*">PROPAGATION_REQUIRED</prop>
				<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
				<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
			</props>
		</property>
	</bean>

 b.使用sping AOP

               <tx:annotation-driven transaction-manager="transactionManager" />    //配置事务管理器

	<tx:advice id="defaultTxAdvice" transaction-manager="transactionManager">    //事务属性
		<tx:attributes>
			<tx:method name="*Transaction" propagation="REQUIRED"  //propagation 事务传播类型
				rollback-for="Exception" />//所有exception回滚,相对的还有no-rollback-for属性
			<tx:method name="find*" propagation="SUPPORTS" read-only="true" />//read-only="true"事务只读
			<tx:method name="get*" propagation="SUPPORTS" read-only="true" />
			<tx:method name="fetch*" propagation="SUPPORTS" read-only="true" />
			<tx:method name="is*" propagation="SUPPORTS" read-only="true" />
			<tx:method name="*_noTrans" propagation="NOT_SUPPORTED" />
		</tx:attributes>
	</tx:advice>

	<aop:config>
		<aop:pointcut id="allManagerMethod"   //切点
			expression=" (
                                     execution(* com.managerment.service.impl..*.*(..))  //第一个*与包路径之间有空格
                                 //第一个* :任何返回类型  第二个*  :impl下所有的类 第三个*: 所有的方法   第一个.. (即impl..) :impl下的所有子包 第二个.. (即(..)):所有参数
                                                                                                             
                          ) " />
		<aop:advisor advice-ref="defaultTxAdvice" pointcut-ref="allManagerMethod" />//通知
	</aop:config>

 

    

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值