spring 事务控制(传播级别详解以及示例)

1.spring 对事务控制的两种方式

  A.声明式事务配置,在xml中配置事务的数据源,隔离界别,传播策略,切点,切面

    B.通过spring注解的方式

 

spring xml 配置    <!--配置 spring data access 管理器-->

    <bean id="jdbcTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource">
            <ref bean="dataSource"/>
        </property>
    </bean>

    <!--配置事物传播策略,以及隔离级别-->
    <tx:advice id="txAdvice" transaction-manager="jdbcTransactionManager">
        <tx:attributes>
            <!-- 注入事务策略 -->
            <tx:method name="delet*"  propagation="REQUIRED" isolation="READ_COMMITTED" rollback-for="Exception"/>
            <tx:method name="updat*"  propagation="REQUIRED" isolation="READ_COMMITTED" rollback-for="Exception"/>
            <tx:method name="delet*"  propagation="REQUIRED" isolation="READ_COMMITTED" rollback-for="Exception"/>
            <tx:method name="inser*"  propagation="REQUIRED" isolation="READ_COMMITTED" rollback-for="Exception"/>
<!--
            <tx:method name="*" propagation="REQUIRED" isolation="READ_COMMITTED"/>
-->
        </tx:attributes>
    </tx:advice>

    <!-- AOP切面和通知编织在一起 -->
    <aop:config>
<aop:pointcut id="service" expression="(execution(public * *..*.service.impl.*.*(..)))"/> <!-- 注入切点,切点策略 --> <aop:advisor advice-ref="txAdvice" pointcut-ref="service" order="1"/> </aop:config>

spring 注解方式

   @Transactional(propagation = Propagation.NEVER,rollbackFor = Exception.class,isolation=Isolation.READ_COMMITTED)

propagation:事务的传播策略

roobackFor: 事务的回滚策略

isolation:事务的隔离级别

 

2.事务隔离级别

spring 的事务隔离级别有七种

  REQUIRED:要求有事务,没有事务就加一个事务。
  eg:外层方法A没有事务,内层方法B声明了事务,B方法先执行,A方法内异常后发生,数据依然能变更。B事务不受A的影响
    外层方法A有事务,内层方法B有事务,B将和A公用一个事务,A 或B 任何一个有异常都将回滚。
   REQUIRES_NEW:不管外层有没有事务都新加一个事务 (注意:没用通过spring 管理的方法,REQUIRES_NEW 不会生效)
    eg:通过this对象调用的带有事务的方法,解决办法:1.调用其他service中被托管的方法,2.获取spring上下文,获取bean工厂中的实例,调用对应的方法
外层A有事务,内层B声明了新的事务,B异常,A回滚,A异常B不会回滚
类TransationServiceImpl    

@Autowired
    private TransationTestService testService;

@Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class,isolation = Isolation.READ_COMMITTED)
    public void requiresNew() {
       // this.haveTra();   //重点:通过this实例调用的方法,并不会被spring的AOP进行托管,所有不论何时都会回滚
        testService.haveTra();
        dao.insertInfo();
        int i=1/0;
    }



类TransationTestServiceImpl

 @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW,rollbackFor = Exception.class,isolation = Isolation.READ_COMMITTED)
    public void haveTra(){
        dao.insertInfo();
    }
  NESTED:嵌套事务,内存事务是外层事务的一部分,内层事务执行完毕不会立即提交,会和外层事务一起提交
    eg:外层方法A声明了一个嵌套事务,内层方法B声明一个事务,B的事务是A的子事务,B事务会保存一个回滚点savepoint,当B执行完还不会提交,只有到A执行完才会提交,所以不论A或者B任何
   方法有异常,都会回滚。
NESTED和REQUIRES_NEW 区别在于提交的时机不同,NESTED 内层方法等待外层事务一起提交,REQUIRES_NEW 不管外层直接提交
类TransationServiceImpl

 @Autowired
    private TransationTestService testService;

 @Override
    @Transactional(propagation = Propagation.NESTED,rollbackFor = Exception.class,isolation = Isolation.READ_COMMITTED)
    public void requiresNew() {
        testService.haveTra();
        try {    //在此之前刷新数据库事务还未提交
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        dao.insertInfo("2"); //外层执行完毕,两个事务一起提交
        //int i = 1 / 0;

    }

类TransationTestServiceImpl
 @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class,isolation = Isolation.READ_COMMITTED)
    public void haveTra(){
        dao.insertInfo("1");
    }

   

     NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
      eg:外层方法A声明REQUIRE,内层方法B声明NEVER,抛出异常

  SUPPORTS:当前有事务就以事务执行,没有就以非事务执行
   MANDATORY:支持当前的事务,没有事务抛出异常
  
   NOT_SUPPORTED:以非事务的方式运行。


  

  

    

    

  

 

posted @ 2018-12-17 20:50  zero_and_one  阅读(883)  评论(0编辑  收藏  举报