【@Transactional注解】彻底搞懂propagation传播机制

6 篇文章 0 订阅

事务传播机制-propagation

要搞懂事务的传播机制,那么就要明白逻辑事务中各个事务的关系,才能彻底理解事务传播特性。

物理事务与逻辑事务

事务性资源实际打开的事务就是物理事务,如数据库事务。

而Spring会为每个@Transactional注解的方法创建一个事务范围,这种事务无法影响数据库事务的实现,因此可以理解为逻辑事务。

在Spring事务中,各个逻辑事务的关系可以是并列、覆盖或包含。

对于并排:并发情况下,多个线程相互执行自己的事务,互不影响(单指事务异常回滚,不涉及事务隔离)。
.
对于覆盖:是指层层嵌套的方法共用同一个事务,事务的属性由最外围方法的属性值决定。这些方法要么同时执行成功要么同时回滚。
.
对于包含:大范围的事务称为外围事务,小范围的事务称为内部事务,外围事务可以包含内部事务。他们在逻辑上是互相独立的。每个内部事务,都能独立设置如read-only等属性,而不影响外围事务。

如何处理逻辑事务内部以及与物理事务之间的关联关系,就是传播特性解决的问题。




事务的传播类型

  1. REQUIRED:Spring默认的事务传播机制。支持当前事务;如果不存在事务,则创建一个新的事务。

参与到一个已存在的更大范围的外围事务中,如果没有外围事务,就打开一个新事务用于当前范围。在相同的线程中,这是一种很好的事务安排方式。

注:一个参与到外围事务的事务,会使用外围事务的特性,安静地忽略掉自己的隔离级别,超时值,只读标识等设置。

当然可以在事务管理器上设置validateExistingTransactions标识为true,这样当你自己的事务和参与到的外围事务设置不一样时会被拒绝。

  1. REQUIRES_NEW:创建一个新事务,如果当前存在事务,则暂停当前事务。

与REQUIRED相比,总是使用一个独立的事务用于当前的逻辑事务,从来不参与到一个已存在的外围事务范围。

这样安排的话,底层的事务资源是不同的,因此,可以独立地提交或回滚。外围事务不会被内部事务的回滚状态影响。

这样一个独立的内部事务可以声明自己的隔离级别,超时时间和只读设置,并不继承外围事务的特性,也不会被外围事务覆盖。

与NOT_SUPPORTED类似,我们需要JTATransactionManager来实现实际的事务暂停。

  1. MANDATORY(强制的):仅支持当前事务;如果当前事务不存在,则抛出异常。

  2. NESTED(嵌套):如果存在当前事务,则在该事务种嵌套执行。同时将在这段逻辑事务开始处标记一个保存点,当这个逻辑事务抛出异常回滚时,那么事务将跳转到保存点,从而不影响嵌套事务的外部。
    当前事务不存在时,同REQUIRED。

当事务存在时,使用同一个事务,该事务可能会带有多个保存点,回滚到这些保存点从而不会影响整个事务。可以认为是部分回滚,这样一个内部事务范围触发了一个回滚,外围事务能够继续这个物理事务,尽管有一些操作已经被回滚。

DataSourceTransactionManager支持这种开箱即用的传播。

JTATransactionManager的一些实现也可能支持这一点。不过JpaTransactionManager仅支持JDBC连接的NESTED,
如果我们将nestedTransactionAllowed标志设置为true,且JDBC驱动程序支持保存点,它也适用于JPA事务中的JDBC访问代码。

  1. NEVER:非事务执行,如果存在事务,则抛出异常。

  2. SUPPORTS:支持当前事务,如果不存在则以非事务方式执行。

  3. NOT_SUPPORTED:以非事务方式执行,如果当前事务存在,则挂起当前事务。

JTATransactionManager开箱即用地支持真正的事务暂停。其他人通过持有对现有的引用然后从线程上下文中清除它来模拟暂停

  1. TIMEOUT_DEFAULT:使用默认超时的底层事务系统,或者如果不支持超时则没有。

全文链接:声明式事务注解:@Transactional

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值