3

01.事务的传播机制

 3 years ago
source link: http://sunliangliang.com/?p=52
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

01.事务的传播机制

发表于 2021-04-13 | 分类于 分布式事务 | 0 | 阅读次数 5

上一篇文章主要讲解了mysql中一些事务的基本知识,但是我们在工作中基本是不会直接操作mysql的事务的,而是通过spring框架来处理的。这一篇就来研究下spring中的事务。

  • spring对于事务的支持
  • 事务的传播机制
  • Spring事务的源码剖析
  • spring执行某个操作,前9次成功,第10次失败。以下分别对应什么传播机制?
    • A:全部回滚
    • B:前9次提交,第10次回滚

1.Spring对于事务的支持

1.1.声明式事务

即我们最常使用的@Transactional注解。

使用@Transactional注解时一般要标注上如下两个参数

  • rollbackFor: 指定异常回滚。一般是RuntimeException
  • propagation: 事务的隔离级别这个我们一般采用了默认的PROPAGATION_REQUIRED

1.2编程式事务

现在一般没人用了,通过TransactionTemplate来实现,此处不再赘述

2.事务的传播机制

我们在数据库中使用事务的时候,是通过事务开始-->业务逻辑-->事务结束这样的流程进行的,是针对不同的单个事务。

而在Java业务代码中,通常是在一个方法上进行的事务操作,通过@Transactional来实现,因此就涉及到了同一个事务操作涉及到多个方法的调用,

并且多个方法有可能不在一个事务中,那么这多个方法是分别提交各自的事务,还是需要合并到外层的事务一起提交,这就是我们事务的传播机制要做的事务了。

2.1.事务的案例

这里用两个类来演示一个事务的传播

ServiceA:作为事务的发起者,会调用另一个类

ServiceB:被调用者

ClassA

public class ServiceA {

@Autowired
  private ServiceB b;

@Transactional
  public void methodA() {
// 一坨数据库操作
    for(int i = 0; i < 51; i++) {
      try {
        b.methodB();
      } catch(Exception e) {
// 打印异常日志
      }
    }
// 一坨数据库操作
  }

}

ClassB

public class ServiceB {

@Transactional(propagation = PROPAGATION_REQUIRES_NEW)
  public void methodB() {

}

}

这里结合两个常用的事务REQUIREDREQUIRES_NEW传播机制,来说明下上面的业务会发生什么

  • REQUIRED

    • @Transactional(propagation = Propagation.REQUIRED,rollbackFor = RuntimeException.class)
    • 不管methodB()是否加事务,都会使用A的事务,即A或者B中有失败,都整体回滚

    • REQUIRES_NEW

      • @Transactional(propagation = Propagation.REQUIRES_NEW,rollbackFor = RuntimeException.class)
      • 嵌套的事务是独立的事务,不会影响外面的事务

      • B会强制开启一个新事务,A的事务会卡主,执行完B的然后执行A的,若A报错,则B不受影响

2.2.事务的传播机制

spring一共定义了7种传播机制。但是我们常用的也就是上面那两种

传播机制 作用 PROPAGATION_REQUIRED Spring默认的传播机制,ServiceA.method()-->ServiceB.method,若A和B都声明了事务,则B不会独立开启事务,将B的事务放到A中一起执行,A和B任意一个报错都会整体回滚 PROPAGATION_REQUES_NEW ServiceB会强制开启一个新的事务,执行的时候ServiceA会卡主等待B执行完毕之后再继续。若A报错,B不受影响,B报错,A可以选择性的回滚或者提交 PROPAGATION_SUPPORT 如果外层有事务,则加入外层事务,如果外层没有事务,则直接使用非事务方式执行。完全依赖外层的事务 PROPAGATION_NOT_SUPPORT 该传播机制不支持事务,如果外层存在事务则挂起,执行完当前代码,则恢复外层事务,无论是否异常都不会回滚当前的代码 PROPAGATION_NEVER 该传播机制不支持外层事务,即如果外层有事务就抛出异常 PROPAGATION_MANDATORY 与NEVER相反,如果外层没有事务,则抛出异常 PROPAGATION_NESTED 该传播机制的特点是可以保存状态保存点,当前事务回滚到某一个点,从而避免所有的嵌套事务都回滚,即各自回滚各自的,如果子事务没有把异常吃掉,基本还是会引起全部回滚的。

2.3.问题解答

针对开头的spring传播机制的面试题目,可以有如下解答:

  • A:两个事务都设置为REQUIRED,这个是毋庸置疑的,全部成功或者全部失败
  • B:将B设置为REQUES_NEW,B每次的调用都在独立事务执行,这样即使第10次失败,也只是回顾最后一次的操作,签名都是独立的事务成功了。

spring事务的实现

更多内容可关注公众号

坚持有质量的创作,您的支持将支持我继续创作!

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK