一图看懂Spring事务传播的本质

22 篇文章 0 订阅
8 篇文章 0 订阅

一图看懂Spring事务传播的本质

一、事务传播本质

可能有点标题党,当可以作为一种思路。
总所周知,Spring事务传播有7种方式,我们经常会苦于记忆和理解。这是因为我们不理解他的本质,如下图:
在这里插入图片描述
同一个线程里关于事务的上下文会记录着当前线程拥有的MySQL Client socket,
每一个Socket只存在一个当前事务(后面会提到为什么)

事务的传播行为本质上是,当前service方法根据当先线程上下文是否存在事务,以此决定后续针对事务后续操作的行为。

最常见的行为,就是根据当前线程事务上下文决定是否创建新事务(如果有则,不做任务操作,等于跟当前线程的父方法共用一个事务; 如果没有,则创建一个新事务,只给自己service方法使用),这个就是 Requested 事务传播类型,也是最常见的。

后面还有,

  • 根据事务上下文决定是否抛异常的极端操作。

  • 根据事务上下文决定是否使用Spring的 “suspend事务机制”,创建新连接获取新事务。

  • 根据事务上下文决定是否启用 Savepoint 机制 (需要Mysql服务器支持)。

二、个人观点:为什么不建议过分依赖 “事务传播”

事务是一种增强DB操作的行为,他可以做到,当操作发生异常的时候,尽量的避免脏数据,帮助我们减少修数据的工作,这是他的本质工作。

所以,

  • 如果对事务没有要求的话,用 Support 类型事务传播,
  • 如果对事务有要求的话,用 Request 类型事务传播。

有人说,

“吖,那要是我有个类似日志记录这种类型的操作,无论如何都不允许被事务会滚,该怎么处理?难道可以不用 Not-Support ?

我的答案是,建议不用,因为会使得代码很晦涩,毕竟Not-support 用到了Spring自创的 “Suspend机制”,把这种有特殊诉求的方法,

用这种隐晦的机制去实现,可读性和维护性不是很高

下面重点是研究 Spring 挂起事务的机制,当然我觉得这个很少用到,不看也是可以的。

三、什么是挂起事务?(MySQL可没有这个概念)

Mysql规定一个连接只能持有一个当前事务,

没有suspend挂起的概念,Spring如何实现的呢?

Spring在框架自身独创(不依赖DB)suspend机制,

所谓的挂起当前事务,开启新的事务,
是 Spring 又去申请了一个新的 Connection,这样就会对应到一个新的事务上,然后将这个连接绑定到当前线程,再继续执行;

当事务创建时,就会被绑定到一个线程上。该线程会伴随着事务整个生命周期,直到事务提交、回滚或挂起(临时解绑)。

线程和事务的关系是1:1,当线程绑定了一个事务后,其他事务不可以再绑定该线程,反之亦然(一个事务只能被一个线程拥有)。

四、为什么一个连接只能有一个MySQL innodb事务呢?

因为MySQL的请求是同步的,所有MySQL发起的客户端请求是同步串行发给MySQL服务器处理的,所以,一个MySQL连接有且只有一个当前事务。(这个是Innodb的设计使然,如果不考虑事务并发,它是一种简单易维护的设计)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值