Spring4基础 学习笔记(6) ---- Spring事务管理

Spring事务管理:Spring通过以下三种方式自实现对事务的管理(事务本来是在Dao层的概念,但是业务层调用Dao,所以业务层调用Dao时也需要使用事务)
1)使用Spring的事务代理工厂管理事务
2)使用Spring的事务注解管理事务
3)使用AspectJ的AOP配置管理事务
 
Spring事务管理API
     1)事务管理接口:PlatFormTransactionManager接口对象(事务管理器)用于完成事务的提交、回滚以及获取事务的状态信息
     常用的实现类:
DataSourceTransactionManager:使用JDBC或者ibatis进行持久化数据时使用
HibernateTransactionManager:使用Hibernate进行持久化
     
 
Spring事务的默认回滚方式是:发生运行时异常(RuntimeException,/0,下标越界,程序无法处理) 回滚,发生受查异常(程序可以处理,继承自Exception)时提交。对于也可以受查异常,也可以设置其回滚方式(运行时异常严重)
 
2)事务定义接口TransactionDefinition:
定义了五事务隔离级别常量:ISOLATION_DEFAULT...
 
定义了七个事务传播行为常量:PROPAGATION_
     指的是不同事务的方法在相互调用时的情况
a)REQUIRED(默认值):该传播行为加载doOther上,
如果doSome调用doOther时就是在事务内运行的,则doOther加入到doSome的事务中;
如果doSome方法没有在事务内执行,则doOther创建一个事务(doOther内beginTransaction   endTransaction)并在其中执行
b)SUPPORT:
如果doSome有事务,doOther在doSome事务下运行
doSome没有事务,doOther可以在没有事务下运行
c)MANDATORY:
指定的方法必须在当前事务内执行,若当前没有事务则doOther抛出异常
d)REQUIRES_NEW:
     总是新建一个事务,若当前存在事务,将当前事务挂起,直到新事务提交
e)NOT_SUPPORTED
doSome有事务,将doSome事务挂起,doOther在无事务下运行
doSome没有事务,doOther直接在无事务下运行。
f)NEVER:
          指定的方法不能在事务下运行
g)NESTED:指定的方法必须在事务内运行
doSome有事务,doOther内开启事务,doSome的事务不挂起
doSome无事务,doOther内beginTransaction,endTransaction
 
定义了默认事务超时时限:
常量TIMEOUT_DEFAULT定义了事务底层默认的超时时限。一般使用默认值
 
 
BuyStockService项目:
1)使用Spring的事务代理工厂bean管理事务 : 即serviceImpl的代理,将事务添加到service中,将service调用的Dao方法绑定在一个事务中(AOP!),即serviceImpl的方法前后加上begin transcation 和 commit
 
      <!-- 注册事务管理器 -->
      <bean id="TransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="c3p0Source"/>
      </bean>     
      
      <!-- 生成service的事务代理对象,在连接点上切入事务而不污染代码 -->
      <bean id="servicProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
            <!-- 目标对象 -->
            <property name="target" ref="buyStockService"/>
            <property name="transactionManager" ref="TransactionManager"/>
            <!-- 这里指明的是在 连接点 方法上要应用什么 事务属性 -->
            <property name="transactionAttributes">
                  <props>
                        //在open*匹配的方法上使用这个事务属性
                        <prop key="open*">ISOLATION_DEFAULT,PROPAGATION_REQUIRED</prop>
                        <prop key="buyStock">ISOLATION_DEFAULT,PROPAGATION_REQUIRED</prop>
                  </props>
            </property>
 
默认的是发生  受查异常  提交,所以做以下配置:
<prop key="buyStock">ISOLATION_DEFAULT,PROPAGATION_REQUIRED,-BuyStockException</prop>
 
- 号的意思是回滚,意思是发生BuyStockException异常回滚
+是提交,如果+运行时异常,会提交
 
 
2)使用Spring的事务注解管理事务:需要使用事务的标签(约束)
 
     <!-- 注册事务管理器 -->
      <bean id="TransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="c3p0Source"/>
      </bean>     
      <!-- 注册事务注解驱动 -->
      <tx:annotation-driven transaction-manager="TransactionManager"/>
 
添加注解:
      @Transactional(isolation=Isolation.DEFAULT,propagation=Propagation.REQUIRED,rollbackFor=BuyStockException.class)
      @Override
      public void buyStock(String aname, int money, String sname, int count) throws BuyStockException{
            // TODO Auto-generated method stub
            Boolean isBuy = true;
            adao.updateAccount(aname,money,isBuy);
            if(true) {
                  throw new BuyStockException();
            }
            sdao.updateStock(sname,count,isBuy);
      }
 
3)使用AspectJ的XML配置管理事务(重点):导入两个JAR包
     
     <!-- 注册事务管理器 -->
      <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="c3p0Source"/>
      </bean>     
      <tx:advice id="txAdvice" transaction-manager="transactionManager">
            <tx:attributes>
                  <!-- 配置的是连接点方法的事务属性 -->
                  <tx:method name="open*" isolation="DEFAULT" propagation="REQUIRED"/>
                  <tx:method name="buyStock" isolation="DEFAULT" propagation="REQUIRED" rollback-for="BuyStockException"/>
            </tx:attributes>
      </tx:advice>
      <!-- 使用AspectJ 的AOP-->
      <aop:config>
            <!-- 这里配置切入点,只有切入了才有效,这里为所有方法切入 -->
            <aop:advisor advice-ref="txAdvice" pointcut="execution(* *..service.*.*(..))"/>
      </aop:config>
posted @ 2018-04-25 23:06  CoderLynn  阅读(263)  评论(0编辑  收藏  举报