实例详解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

时间: 2024-10-25 06:09:56

实例详解Spring的事务传播机制(三)的相关文章

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

上面我们讨论了NEVER和MANDATORY的作用,下面我们接着讨论其他情况. 3. SUPPORTS 如果有事务则加入该事务,如果没有存在的事务则以非事务的方式运行. 我们先让insertSubTable方法在无事务的情况下运行.配置文件为: <tx:attributes>       <!--     <tx:method name="insertSuperTable" propagation="REQUIRED"/>      -

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

Spring有7种事务传播机制,本文主要用实例说明各种传播机制的事务效果,和发生异常的回滚方式.7种事务传播机制网上的资料大多都是如下的描述: 事务传播行为类型 说明 PROPAGATION_REQUIRED 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中.这是最常见的选择. PROPAGATION_SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行. PROPAGATION_MANDATORY 使用当前的事务,如果当前没有事务,就抛出异常. PRO

《AngularJS》5个实例详解Directive(指令)机制(转)

转自大漠穷秋:http://damoqiongqiu.iteye.com/blog/1917971 感谢作者分享! <AngularJS>5个实例详解Directive(指令)机制 大漠穷秋 本文整理并扩展了<AngularJS>这本书第六章里面的内容,此书近期即将由电子工业出版社出版,敬请期待口令:Angular 1.一点小说明 指令的作用:实现语义化标签 我们常用的HTML标签是这样的: <div> <span>一点点内容</span> &l

RabbitMQ实例详解+Spring中的MQ使用

RabbitMQ实例详解 消息队列中间件是分布式系统中重要的组件,主要解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构. Queue Queue(队列)是RabbitMQ的内部对象,用于存储消息,用下图表示. RabbitMQ中的消息都只能存储在Queue中,生产者(下图中的P)生产消息并最终投递到Queue中,消费者(下图中的C)可以从Queue中获取消息并消费. 多个消费者可以订阅同一个Queue,这时Queue中的消息会被平均分摊给多个消费者进行处理,而不

spring事务中隔离级别和spring的事务传播机制

Transaction 也就是所谓的事务了,通俗理解就是一件事情.从小,父母就教育我们,做事情要有始有终,不能半途而废. 事务也是这样,不能做一般就不做了,要么做完,要 么就不做.也就是说,事务必须是一个不可分割的整体,就像我们在化学课里学到的原子,原子是构成物质的最小单位.于是,人们就归纳出事务的第一个特性:原子性(Atomicity).我靠,一点都不神秘嘛. 特别是在数据库领域,事务是一个非常重要的概念,除了原子性以外,它还有一个极其重要的特性,那就是:一致性(Consistency).也就

Spring的事务传播机制

1.事务传播类型     新建事务 required required_new   - 挂起当前    非事务方式运行 supports not_supported  - 挂起当前 never    嵌套事务: nested    抛异常 mandatory never 2. PROPAGATION_REQUIRED 加入当前正要执行的事务不在另外一个事务里,那么就起一个新的事务. 3.PROPAGATION_SUPPORTS 如果当前在事务中,即以事务的形式运行,如果当前不再一个事务中,那么就

《AngularJS》5个实例详解Directive(指令)机制

本文整理并扩展了<AngularJS>这本书第六章里面的内容,此书近期即将由电子工业出版社出版,敬请期待口令:Angular 1.一点小说明 指令的作用:实现语义化标签 我们常用的HTML标签是这样的: <div> <span>一点点内容</span> </div> 而使用AngularJS的directive(指令)机制,我们可以实现这样的东西: <tabpanel> <panel>子面板1</panel>

一文详解Spring Cloud Feign重试机制

前言 Feign组件默认使用Ribbon的重试机制并增加了根据状态码判断重试机制,默认情况下是不启用的.Feign使用的是Spring Retry组件,需要引入依赖才能启用. 一.POM引入Spring Retry <dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> </dependency> 二

Spring 管理Hibernate事务之事务传播机制

public enum Propagation {    REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED),    SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS),    MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY),    NOT_SUPPORTED(TransactionDefinition.PROPAGATION_