【Spring事物三千问】TransactionSynchronizationManager的原理分析

这篇具有很好参考价值的文章主要介绍了【Spring事物三千问】TransactionSynchronizationManager的原理分析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

TransactionSynchronizationManager

TransactionSynchronizationManager 是管理每个线程的DB连接资源和事务同步的核心委托类。

如果事务同步未处于活动状态,则表示当前没有事务,或者事务管理器不支持事务同步。

TransactionSynchronizationManager 中定义了很多 ThreadLocal 变量,来保存事务相关的信息

public abstract class TransactionSynchronizationManager {

    // 保存DB连接资源。
    // 使用 Object 来保存是因为每种平台的DB连接资源对象可能不一样,比如:JDBC,Hibernate,EJB 等使用的 DB 连接对象是不一样的。 
    private static final ThreadLocal<Map<Object, Object>> resources = new NamedThreadLocal<>("Transactional resources");

    // 事务同步回调。每个线程可以注册多个事务同步回调
    private static final ThreadLocal<Set<TransactionSynchronization>> synchronizations = new NamedThreadLocal<>("Transaction synchronizations");
    
    // 当前事务的名称  
    private static final ThreadLocal<String> currentTransactionName = new NamedThreadLocal<>("Current transaction name");
    // 当前事务是否只读  
    private static final ThreadLocal<Boolean> currentTransactionReadOnly = new NamedThreadLocal<>("Current transaction read-only status");
    // 当前事务的隔离级别  
    private static final ThreadLocal<Integer> currentTransactionIsolationLevel = new NamedThreadLocal<>("Current transaction isolation level");
    // 事务是否开启  
    private static final ThreadLocal<Boolean> actualTransactionActive = new NamedThreadLocal<>("Actual transaction active");
}

不同的平台的DB连接资源对象可能是不一样的,反映在 Spring 源码当中就是调用 TransactionSynchronizationManager#bindResource() 方法时,绑定的 DB 连接资源不同。

TransactionSynchronizationManager 事务同步管理器的核心逻辑

  • 为什么要使用事务同步管理器 TransactionSynchronizationManager?
    答:不同平台的事务管理实现方式不同,DB 连接资源对象也可能不同,所以,通过 TransactionSynchronizationManager 将事务资源相关的信息保存在各个 ThreadLocal 对象中,可以隔离不同平台带来的差异。

将当前 DB 连接资源绑定到当前线程中的代码如下:
【Spring事物三千问】TransactionSynchronizationManager的原理分析

不管是什么平台,Spring 封装的获取 DB 连接资源的编程模型都是统一的:

  1. 从当前线程中获取绑定的 DB 连接资源 — TransactionSynchronizationManager#getResource()
  2. 如果没有获取到,则从 DataSource 中获取 DB 连接资源
  3. 将获取到的 DB 连接资源绑定到当前线程中 — TransactionSynchronizationManager#bindResource()

TransactionSynchronization 事务回调扩展

Spring 会通过 AbstractPlatformTransactionManager#processCommit() 去处理事务的提交,在事务提交前后预留了一些扩展点。

处理事务提交的代码如下:
【Spring事物三千问】TransactionSynchronizationManager的原理分析

可以看到,事务提交前后有一些 triggerXxx 方法是 Spring 预留的扩展点。底层是调用当前线程中注册的事务同步回调 TransactionSynchronization 中的方法。

// TransactionSynchronizationUtils#triggerBeforeCommit()  
public static void triggerBeforeCommit(boolean readOnly) {
    for (TransactionSynchronization synchronization : TransactionSynchronizationManager.getSynchronizations()) {
        synchronization.beforeCommit(readOnly);
    }
}

事务回调的扩展方法有: triggerBeforeCommit()、triggerBeforeCompletion()、triggerAfterCommit()、triggerAfterCompletion()
参考: org.springframework.transaction.support.TransactionSynchronization

https://www.cnblogs.com/kkkfff/p/13778692.html
https://carlzone.blog.csdn.net/article/details/108659198

慎用事务回调扩展

问题一:triggerXx 方法中操作数据库的话,对原事物是否有影响?

TransactionSynchronization 扩展出的方法中,能不能在方法里面操作数据库,要打个问号??
这里面带来的问题是:如果在 triggerXx 方法中操作数据库,是新开启一个连接,还是在原来的事务连接中进行操作?
如果操作不当,容易引发问题,要慎用! https://www.jianshu.com/p/149de22ca54b

其实,这些预留扩展的 trigger 方法都可以通过其他变通的方式来书写,没必要一定要使用。在博主的工作中,还从未碰到过不使用 trigger 扩展解决不了的场景。

问题二:triggerAfterCommit()、triggerAfterCompletion()

在阅读源码的过程中,可以发现:
在 triggerAfterCommit()、triggerAfterCompletion() 中使用事物的话,不会对上层事物产生任何影响了,因为 spring-tx 对异常的处理没有包含 triggerAfterCommit()、triggerAfterCompletion(),
所以,上层事物不会再处理 triggerAfterCommit()、triggerAfterCompletion() 方法里面抛出的异常。

还有个问题是需要尤其注意的,triggerAfterCommit()、triggerAfterCompletion() 方法中使用事物的话,还有一个风险,内外事物如果使用的是同一个事物的话,那么,事物连接在这个时候可能已经被
连接池回收了,从而导致诡异的问题。

可以参看源码注释: org.springframework.transaction.support.TransactionSynchronization#afterCompletion
TransactionSynchronization#afterCommit 与 TransactionSynchronization#afterCompletion 是类似的。文章来源地址https://www.toymoban.com/news/detail-405142.html

Invoked after transaction commit/rollback. Can perform resource cleanup after transaction completion.
NOTE: The transaction will have been committed or rolled back already, but the transactional resources might still be active and accessible.
As a consequence, any data access code triggered at this point will still "participate" in the original transaction, 
allowing to perform some cleanup (with no commit following anymore!), unless it explicitly declares that it needs to run in a separate transaction. 
Hence: Use PROPAGATION_REQUIRES_NEW for any transactional operation that is called from here.

到了这里,关于【Spring事物三千问】TransactionSynchronizationManager的原理分析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • spring事物初始化过程分析

    1.注入4个bd 2.执行 org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessBeforeInstantiation 逻辑分析:遍历所有的bd: 获取beanname-判断beanname是否有长度并且没有被处理过-是否遍历放入advisedBeans- 是否是基础类-是否该跳过  4大基础类 3.执行org.springframework.aop.framework.autoprox

    2024年02月02日
    浏览(25)
  • 学会@ConfigurationProperties月薪过三千

    学习 @ConfigurationProperties 之前我们需要一些前置知识点: @Value是个什么东西 首先明确: @ConfigurationProperties 是 SpringBoot 注解。 我们在讲 @Value 时知道了如何将配置文件的属性注入到变量中,废话不多说,直接上代码。 这是配置文件配置: 麻烦? 没事,有简单的,我们用简单

    2024年02月03日
    浏览(25)
  • 历史本质是就是新生事物替代旧事物的过程,要保持对新生事物的关注,伺机拥抱

    当今这瞬息万变,时代变迁的洪流中,每一天都在诞生新生事物,每一天都在产生新的可能性,未来的某一天这些新事物就会取代旧事物立在时代的潮头。 从哲学角度来看,万事万物都是不断处于运动和发展中的,一个事物终将被另一个新生事物取代是宿命,这就要求人在享

    2024年02月08日
    浏览(29)
  • super父类 事物

    一个没有事物的方法。 调用他的父类里有事物的方法。 无论this 和 super 都会让父类事物方法没有事物。 如果写了super.class 文件里面,就是super调用。 如果没写,就是this调用,坑爹 测试,把父类注入,事物才生效。

    2024年02月14日
    浏览(24)
  • MySQL事物

    事务是一组SQL语句的执行,要么全部成功,要么全部失败,不能出现部分成功,部分失败的结果,保证事务执行的原子操作 事务的所有SQL语句全部执行成功,才能提交(commit)事务,把结果写回磁盘上 事务执行过程中,有的SQL出现错误,那么事务必须要回滚(rollback)到最初

    2023年04月08日
    浏览(27)
  • UML之四种事物

    目录 结构事物 行为事物 分组事物: 注释事物 1.类(Class)    -类是对一组具有相同属性、方法、关系和语义的对象的描述。一个类实现一个或多个接口 2.接口(interface)  -接口描述 了一个类或构件的一个服务的操作集。接口仅仅是定义了一组操作的规范,它并没有给出这组操

    2024年02月13日
    浏览(18)
  • 02 表达客观事物的术语

    (1)定义与表示 类(Class): 是一组具有相同属性、操作、关系和语义的对象 的描述。 对象(object): 对象是类的一个实例。 依据类出现的场景,可以给出如下简化的表示: 类可以是抽象类,即没有实例的类,此时类名采用斜体字: (2)类名(类的标识) ①类名使用 黑体字 , 第

    2024年02月08日
    浏览(18)
  • MySQL----事物与存储引擎

    事务是一种机制、一个操作序列,包含了一组数据库操作命令(增删改),并且把所有的命令作为一个整体一起向系统提交或撤销操作请求,即这一组数据库命令要么都执行,要么都不执行。 事务是一个不可分割的工作逻辑单元, 在数据库系统上执行并发操作时,事务是最

    2024年02月10日
    浏览(41)
  • MySQL中的事物

    目录 一、背景 二、事物的概念 概念: 回滚: 三、事物的特性 1、原子性 2、一致性 3、持久性 4、隔离性 四、并发执行的三个典型bug 1、脏读 2、不可重复读 3、幻读 五、MySQL的隔离级别 1、read uncommitted 读未提交 2、read committed 读已提交 3、repeatable read 可重复读 4、serializabl

    2024年02月05日
    浏览(31)
  • SpringBoot系列:事物创建过程(二)

    SpringBoot系列:事物加载过程(一) SpringBoot系列:事物创建过程(二) SpringBoot系列:事物提交回滚过程(三) 上一节讲述了事物的加载过程,最后生成代理文件,放到spring容器中。 代理类继承了 被代理类, 实现了两个 SpringProxy , Advised , Factory 接口, methodInterceptor 是 Dynami

    2023年04月09日
    浏览(24)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包