spring-hibernate事务管理

<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

 xmlns:p="http://www.springframework.org/schema/p"


 xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
 xsi:schemaLocation="
 http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
 
 http://www.springframework.org/schema/tx
 http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
 
 http://www.springframework.org/schema/aop
 http://www.springframework.org/schema/aop/spring-aop-3.0.xsd

 

<bean id="sessionFactory"
  class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
  <property name="configLocation" value="classpath:hibernate.cfg.xml">
  </property>
 </bean>
 <bean id="txManager"
  class="org.springframework.orm.hibernate3.HibernateTransactionManager"
  p:sessionFactory-ref="sessionFactory"></bean>
 <tx:advice id="tx" transaction-manager="txManager">

//规则
  <tx:attributes>
   <tx:method name="get*" propagation="SUPPORTS"/>
   <tx:method name="login*" propagation="SUPPORTS"/>
   <tx:method name="find*" propagation="SUPPORTS"/>
   <tx:method name="query*" propagation="SUPPORTS"/>

   // 其他 方法 用这个实现
   <tx:method name="*" propagation="REQUIRED" />
  </tx:attributes>
 </tx:advice> 
 <aop:config>

//切面
  <aop:pointcut expression="within(cn.zf.biz..*)" id="zfcut"/>
  <aop:advisor advice-ref="tx" pointcut-ref="zfcut"/>
 </aop:config> 

所有的dao必须用接口实现

-- Spring中事务的Propagation(传播性)的取值
    -- PROPAGATION_REQUIRED
       -- 加入当前已有事务;只有当前没有事务才起一个新的事务
       比如说,ServiceB.methodB的事务级别定义为PROPAGATION_REQUIRED, 那么由于ServiceA.methodA的时候,ServiceA.methodA已经起了事务,这时调用ServiceB.methodB,ServiceB.methodB看到自己已经运行在ServiceA.methodA的事务内部,就不再起新的事务。而假如ServiceA.methodA运行的时候发现自己没有在事务中,它就会为自己分配一个事务。这样,在ServiceA.methodA或者在ServiceB.methodB内的任何地方出现异常,事务都会被回滚。
    -- PROPAGATION_SUPPORTS
       -- 如果当前在事务中,即以事务的形式运行,如果当前不在一个事务中,那么就以非事务的形式运行
    -- PROPAGATION_MANDATORY
       -- 必须在一个事务中运行。也就是说,只能被一个父事务调用。否则,就要抛出异常。
    -- PROPAGATION_REQUIRES_NEW
       -- 比如我们设计ServiceA.methodA的事务级别为PROPAGATION_REQUIRED,ServiceB.methodB的事务级别为PROPAGATION_REQUIRES_NEW,那么当执行到ServiceB.methodB的时候,ServiceA.methodA所在的事务就会挂起,ServiceB.methodB会起一个新的事务,等待ServiceB.methodB的事务完成以后,它才继续执行。它与PROPAGATION_REQUIRED 的事务区别在于事务的回滚程度了。因为ServiceB.methodB是新起一个事务,那么就是存在两个不同的事务。如果ServiceB.methodB已经提交,那么ServiceA.methodA失败回滚,ServiceB.methodB是不会回滚的。如果ServiceB.methodB失败回滚,它抛出的异常被ServiceA.methodA捕获,ServiceA.methodA事务仍然可以提交。
    -- PROPAGATION_NOT_SUPPORTED
       -- 当前不支持事务。比如ServiceA.methodA的事务级别是PROPAGATION_REQUIRED ,而ServiceB.methodB的事务级别是PROPAGATION_NOT_SUPPORTED,
       那么当执行到ServiceB.methodB时,ServiceA.methodA的事务挂起,而它以非事务的状态运行完,再继续ServiceA.methodA的事务。
    -- PROPAGATION_NEVER
       -- 不能在事务中运行。假设ServiceA.methodA的事务级别是PROPAGATION_REQUIRED, 而ServiceB.methodB的事务级别是PROPAGATION_NEVER,那么ServiceB.methodB就要抛出异常了。
    -- PROPAGATION_NESTED
       -- 理解Nested的关键是savepoint。它与PROPAGATION_REQUIRES_NEW的区别是,PROPAGATION_REQUIRES_NEW另起一个事务,将会与它的父事务相互独立,而Nested的事务和它的父事务是相依的,它的提交是要等和它的父事务一块提交的。也就是说,如果父事务最后回滚,它也要回滚的。而Nested事务的好处是它有一个savepoint。也就是说ServiceB.methodB失败回滚,那么ServiceA.methodA也会回滚到savepoint点上,ServiceA.methodA可以选择另外一个分支,比如ServiceC.methodC,继续执行,来尝试完成自己的事务。但是这个事务并没有在EJB标准中定义。

 

posted @ 2016-04-06 15:29  随风而逝,只是飘零  阅读(129)  评论(0编辑  收藏  举报