码迷,mamicode.com
首页 > 编程语言 > 详细

实例详解Spring的事务传播机制(三)

时间:2016-04-09 17:09:52      阅读:230      评论:0      收藏:0      [点我收藏+]

标签:spring   事务传播机制   

最后这篇文章我们来讨论开发中最常用的剩下三种事务传播机制:REQUIRED、REQUIRES_NEW和NESTED

5. REQUIRED

REQUIRED是我们最常用的传播机制。如果当前有存在的事务则加入该事务,如果没有则新开一个事务。

先修改配置文件:

<tx:attributes>  
    <tx:method name="insertSuperTable" propagation="REQUIRED"/> 
    <tx:method name="insertSubTable" propagation="REQUIRED"/> 
</tx:attributes>

父事务类:

@Component
public class TransactionSuper {
    @Autowired
    TransactionSub transactionSub;
    String insertSuperTable1 = "insert into super_table values (1, ‘super1‘)";
    String insertSuperTable2 = "insert into super_table values (2, ‘super2‘)";
    
    public void insertSuperTable(AbstractApplicationContext ctx) throws Exception{
    	System.out.println("========insertSuperTable start========");
    	JdbcTemplate jt = (JdbcTemplate)ctx.getBean("jdbcTemplate");
    	jt.execute(insertSuperTable1);
    	transactionSub.insertSubTable(ctx);
    	jt.execute(insertSuperTable2);
    	System.out.println("========insertSuperTable end========");
    }
}

子事务类:

@Component
public class TransactionSub {
    String insertSubTable1 = "insert into sub_table values (1, ‘sub1‘)";
    String insertSubTable2 = "insert into sub_table values (2, ‘sub2‘)";

    public void insertSubTable(AbstractApplicationContext ctx) throws Exception {
        System.out.println("========insertSubTable start========");
        JdbcTemplate jt = (JdbcTemplate) ctx.getBean("jdbcTemplate");
        jt.execute(insertSubTable1);
        jt.execute(insertSubTable2);
        System.out.println("========insertSubTable end========");
    }
}

然后运行测试方法

技术分享

技术分享

技术分享

如果有存在的事务,跟MANDATORY效果一样,也是加入该事务,并且共用一个connection,所以父子方法对数据库的修改都是相互可见的。没有事务的情况这里就不再演示了,也就是insertSubTable方法自己新开一个事务。

我们来看看发生异常时的回滚,其实基本跟MANDATORY一样,只是子方法可以自己开启事务,而不一定要加入其它事务之中

①RuntimeException

如果有已经存在的事务,跟MANDATORY一样,REQUIRED标注的方法是直接加入父事务,成为父事务的一部分,他们共享一个connection。所以不管是子事务还是父事务抛出RuntimeException的时候,父子事务都会回滚。如果没有事务,就只回滚子方法新开事务中的操作。

②Throwable和Exception

MANDATORY一样,如果不配置rollback-for属性,抛出Throwable和Exception都不会导致父子事务回滚,而是在哪儿出异常就在哪儿提交,就有可能出现部分提交的现象。

我们可以用rollback-for属性来让抛Throwable和Exception时也回滚。由于REQUIRED标注的方法是直接加入父事务,所以子类发生Throwable或Exception,就会父子一起回滚。




6. REQUIRES_NEW

REQUIRES_NEW标记的方法会新建事务,如果当前存在事务,把当前事务挂起,等待新开事务完成后,被挂起的事务再恢复执行。

先修改配置文件:

<tx:attributes>  
    <tx:method name="insertSuperTable" propagation="REQUIRED"/> 
    <tx:method name="insertSubTable" propagation="REQUIRES_NEW"/> 
</tx:attributes>

直接执行测试方法:

技术分享

技术分享

技术分享

从上面可以很明显的看出insertSubTable方法新开了一个connection并重启了一个新事务,insertSuperTable和insertSubTable是两个不同的connection中的两个不同的事务。所以父方法对数据库的修改是否对子方法可见,取决于数据库的事务隔离级别。

REQUIRES_NEW由于开了新连接和新事务,所以异常回滚跟其他事务传播机制有很大区别,下面我们结合具体实例来说明。

①RuntimeException

本文出自 “銅鑼衛門” 博客,请务必保留此出处http://jaeger.blog.51cto.com/11064196/1762039

实例详解Spring的事务传播机制(三)

标签:spring   事务传播机制   

原文地址:http://jaeger.blog.51cto.com/11064196/1762039

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!