当前位置: 首页 > news >正文

Seata框架,如何保证事务的隔离性?

写隔离
  • 一阶段本地事务提交前,需要确保先拿到 全局锁

  • 拿不到 全局锁 ,不能提交本地事务。

  • 拿 全局锁 的尝试被限制在一定范围内,超出范围将放弃,并回滚本地事务,释放本地锁。

以一个示例来说明:

两个全局事务 tx1 和 tx2,分别对 a表的 m 字段进行更新操作,m 的初始值 1000

  • tx1 先开始,开启本地事务,拿到本地锁,更新操作 m = 1000-100=900,本地事务提交前,先拿到该记录的全局锁 ,本地提交释放本地锁

  • tx2 后开始,开启本地事务,拿到本地锁,更新操作m= 900-100=800。本地事务提交前,尝试拿该记录的全局锁,t1 全局提交前,该记录的全局锁被 t1 持有,tx2 需要重试等待全局锁

tx1 二阶段全局提交,释放 全局锁。tx2 拿到 全局锁 提交本地事务。

如果 tx1 的二阶段全局回滚,则 tx1 需要重新获取该数据的本地锁,进行反向补偿的更新操作,实现分支的回滚

此时,如果 t2 仍在等待该数据的全局锁,同时持有本地锁,则 tx1的分支回滚会失败。分支的回滚会一直重试,直到 t2 的全局锁等锁超时,放弃 全局锁并回滚本地事务释放本地锁,tx1 的分支回滚最终成功。

因为整个过程 全局锁 在 tx1 结束前一直是被 tx1 持有的,所以不会发生脏写的问题。

读隔离

在数据库本地事务隔离级别 读已提交(Read Committed) 或以上的基础上,AT 模式的默认全局隔离级别是 读未提交(Read Uncommitted)

这里的读未提交是从全局事务的视角来看的。我们知道,在一阶段后,RM 的分支事务其实已经提交了,这时候在数据库层面来说就是读已提交,但是站在整个全局视角来说,只要二阶段还没执行提交或者回滚,整个全局事务都是处于未提交的阶段。

举个例子,有两个全局事务 tx1、tx2。tx1 读库存为 100,tx1 扣减库存 1,此时 before imgge 为 100,此时 tx2 也同时进来读取库存也为 100 那么问题了就来了,如果 tx1 二阶段回滚,不管 tx2 扣减多少库存,都会覆盖掉 tx2 扣减的库存,出现脏写的情况

目前 Seata 的方式是通过 SELECT FOR UPDATE 语句的代理,Seata 会对 SELECT FOR UPDATE 语句进行拦截,会先去查询全局锁, 如果 全局锁 被其他事务持有,则释放本地锁(回滚 SELECT FOR UPDATE 语句的本地执行)并重试。这个过程中,查询是被 block 住的,直到 全局锁 拿到,即读取的相关数据是 已提交 的,才返回。

出于总体性能上的考虑,Seata 目前的方案并没有对所有 SELECT 语句都进行代理,仅针对 FOR UPDATE 的 SELECT 语句。

2. 如果其中一个事务分支超时未提交

Seata的全局事务超时时间,默认是1分钟。当 TC 检测到有超市的全局事务时,会向所有已提交分支事务的 RM 发起回滚

http://www.dtcms.com/a/123044.html

相关文章:

  • 【时时三省】(C语言基础)用switch语句实现多分支选择结构
  • 【运维 | 硬件】服务器中常见的存储插槽类型、对应的传输协议及其特性总结
  • 环信鸿蒙版 UIKit 快速上手指南
  • 如何将多个Word文档合并
  • 【HTML】动态背景效果前端页面
  • 基于 Qt4 的图片处理工具开发(二):增加对比度调节、界面布局优化、多线程操作
  • 初识Redis · 简单理解Redis
  • 使用注解@RequestBody变红的解决问题
  • 【spark认任务提交】配置优先级顺序
  • 银河麒麟v10(arm架构)部署Embedding模型bge-m3【简单版本】
  • 【C++进阶】关联容器:multimap类型
  • 学习海康VisionMaster之四边形查找
  • 【达梦数据库】bash: /dev/null: Permission denied
  • 使用stm32cubeide stm32f407 lan8720a freertos lwip 实现tcp客户端、服务端及网络数据转串口数据过程详解
  • SQL 关键字
  • 低硬件资源微调预训练Mamba模型的方法
  • 在 transformers 中,return_tensors=‘pt‘ 里的 pt 是什么 tf,np
  • gdal_shp文件的组成
  • 【设备连接涂鸦阿里云】
  • [数据结构]Trie字典树
  • RocketMQ和kafka 的区别
  • 算法导论(递归回溯)——⼆叉树中的深搜
  • lanqiaoOJ 498 回文日期
  • ValueError: Cannot handle batch sizes > 1 if no padding token is defined`
  • 数据结构(五)——AVL树(平衡二叉搜索树)
  • 【Python语言基础】17、继承
  • 深入理解 Spring 的 MethodParameter 类
  • 测试的分类
  • OpenCV 图形API(25)图像滤波-----均值滤波(模糊处理)函数blur()
  • 写一个简单的demo来理解数据库外键