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 >

猜你喜欢

转载自www.cnblogs.com/coderlynn/p/8948047.html