阿里面试:Seata如何实现RC?保证事务的隔离性?

尼恩说在前面

在40岁老架构师 尼恩的读者交流群(50+)中,最近有小伙伴拿到了一线互联网企业如阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试资格,遇到很多很重要的面试题:

Seata 如何实现 RC ?保证事务的隔离性?

最近有小伙伴在面试阿里,又遇到了相关的面试题。小伙伴懵了,因为没有遇到过,所以支支吾吾的说了几句,面试官不满意,面试挂了。

所以,尼恩给大家做一下系统化、体系化的梳理,使得大家内力猛增,可以充分展示一下大家雄厚的 “技术肌肉”,让面试官爱到 “不能自已、口水直流”,然后实现”offer直提”。

当然,这道面试题,以及参考答案,也会收入咱们的 《尼恩Java面试宝典PDF》V167版本,供后面的小伙伴参考,提升大家的 3高 架构、设计、开发水平。

《尼恩 架构笔记》《尼恩高并发三部曲》《尼恩Java面试宝典》的PDF,请到文末公号【技术自由圈】获取

文章目录

    • 尼恩说在前面
    • Seata 事务隔离级别解读
    • Seata 全局锁实现 RC
    • Seata事务 + 独立事务 场景的 脏读、脏写
    • 如何防止脏读/脏写
      • 方案一:独立事务执行时加 @GlobalTransactional注解
      • 方案二:独立事务业务二执行时加 @GlobalLock注解
      • 方案三:业务二执行时加 @GlobalLock 注解 + select for update语句
    • 说在最后:有问题找老架构取经
    • 尼恩技术圣经系列PDF

Seata 事务隔离级别解读

先来回顾一下,数据库事务的隔离级别,目前数据库事务的隔离级别一共有 4 种,由低到高分别为:

事务的四个隔离级别:

  • 未提交读(READ UNCOMMITTED):所有事务都可以看到其他事务未提交的修改。一般很少使用;
  • 读已提交(READ COMMITTED):Oracle默认隔离级别,事务之间只能看到彼此已提交的变更修改;
  • 可重复读(REPEATABLE READ):MySQL默认隔离级别,同一事务中的多次查询会看到相同的数据行;可以解决不可重复读,但可能出现幻读;
  • 可串行化(SERIALIZABLE):最高的隔离级别,事务串行的执行,前一个事务执行完,后面的事务会执行。读取每条数据都会加锁,会导致大量的超时和锁争用问题;

数据库一般默认的隔离级别为 读已提交 RC ,比如 Oracle,

也有一些数据的默认隔离级别为 可重复读 RR,比如 Mysql。“可重复读”(Repeatable Read)这个级别确保了对同一字段的多次读取结果是一致的,除非数据是被本身事务自己所修改。它能够防止脏读、不可重复读,但可能会遇到幻读的情况。

参考 文章:

Mysql如何实现RR级隔离时,不会幻读?

MySQL默认的Repeatable Read隔离级别,被改成了RC , 具体请参考 《尼恩Java 面试宝典》 MYSQL 专题:

一般而言,数据库的读已提交(READ COMMITTED)能够满足业务绝大部分场景了。

但是 seata 却做不到 RC, 只能做到RU。

Seata 的事务是一个全局事务,它包含了若干个分支本地事务,在全局事务执行过程中(全局事务还没执行完),某个本地事务提交了,如果 Seata 没有采取任务措施,则会导致已提交的本地事务被读取,造成脏读,如果数据在全局事务提交前已提交的本地事务被修改,则会造成脏写。

由此可以看出,传统意义的脏读是读到了未提交的数据,Seata 脏读是读到了全局事务下未提交的数据,全局事务可能包含多个本地事务,某个本地事务提交了不代表全局事务提交了。

从这个意义上说, seata 的隔离级别是 读未提交。 而实际上,这当中又有绝大多数的应用场景,实际上工作在读未提交的隔离级别下同样没有问题。

如何实现 读已提交?

默认情况下,Seata 的全局事务是工作在读未提交隔离级别的,保证绝大多数场景的高效性。

但是,在极端场景下,应用如果需要达到全局的读已提交,Seata 也提供了全局锁机制实现全局事务读已提交 RC。

Seata 全局锁实现 RC

AT 模式下,会使用 Seata 内部数据源代理 DataSourceProxy,全局锁的实现就是隐藏在这个代理中。

接下来看看, seata at分别在执行、提交的过程都做了什么。

如上所示,一个分布式事务的锁获取流程是这样的

  1. 先获取到本地锁即可修改本地数据,但不能直接提交本地事务
  2. 为何不能直接提交本地事务呢?因为还未获取全局锁
  3. 本地锁和全局锁都获得了,才具有全局事务写隔离的保障,本地事务才可以提交,之后释放本地锁
  4. 当分布式事务执行 2 阶段提交后释放全局锁;这样就可以让其它事务获取全局锁,并提交它们对本地数据的修改了。

至此已明确 Seata 通过将传统 XA 方案的 2 个阶段的本地 DB 锁,拆分成了 本地锁(DB 锁)+ 全局锁的模式 。

如果一个应用所有的事务都用Seata 分布式事务, 性能一定是很低的。 具体请参见 尼恩《Seata 学习圣经 的性能部分内容》。

所以,在大部分业务场景,并不是所有的 操作都要用分布式操作,,并不是所有的 操作都要用分布式事务, 所以生产场景基本上会是 Seata事务 + 独立事务 组合模式。

那么,在 Seata事务 + 独立事务 场景下,Seata 的全局锁对于 外部的 独立事务失效了,对于外部事务,本质上是Seata默认的全局事务是读未提交,能读到seata 未提交(Seata分支已提交的分支事务的数据)的数据,于是,本地事务会发生 脏读。

如何实现 Seata事务 + 独立事务 场景的 RC? 如何解决 独立本地事务的 脏读问题?

Seata事务 + 独立事务 场景的 脏读、脏写

AT 模式是一种非侵入式的分布式事务解决方案,Seata 在内部做了对数据库操作的代理层,我们使用 Seata AT 模式时,实际上用的是 Seata 自带的数据源代理 DataSourceProxy。

Seata 在这层DataSourceProxy 代理中加入了很多逻辑,比如:

  • 插入回滚 undo_log 日志,
  • 检查全局锁等。

为什么要检查全局锁呢,这是由于 Seata AT 模式的事务隔离是建立在支事务的本地隔离级别基础之上的,

在数据库本地隔离级别读已提交或以上的前提下,Seata 设计了由TC维护的全局写排他锁,来保证事务间的写隔离,实现分布式事务的 RC。

先来看一下Seata事务 + 独立事务 场景,使用 Seata AT 模式是怎么产生脏读的:

业务一开启seata 分布式事务,其中包含分支事务A(修改 A)和分支事务 B(修改 B),

业务二开启本地事务,仅仅修改 A,

其中业务一执行分支事务 A 先获取本地锁,

业务二则等待业务一执行完分支事务 A 之后,获得本地锁修改 A 并提交,

业务一在执行分支事务时发生异常了,由于分支事务 A 的数据被业务二修改,导致业务一的全局事务无法回滚,需要人工干预。

这里发生了两种错误的现象:

  • 业务2发生了脏读
  • 业务1 发生了脏写

如何防止脏读 、脏写? 帮助 Seata+ 独立事务 场景实现 RC。

方案有两种:

  • 独立事务 升级为分布式事务
  • 业务二查询 A 时加 @GlobalLock 注解 + select for update语句

如何防止脏读/脏写

Seata AT 模式的脏读是指在全局事务未提交前,被其它业务读到已提交的分支事务的数据,本质上是Seata默认的全局事务是读未提交。

那么怎么避免脏读、脏写现象呢?

方案一:独立事务执行时加 @GlobalTransactional注解

业务二在执行全局事务过程中,分支事务 A 提交前注册分支事务获取全局锁时,发现业务业务一全局锁还没执行完,因此业务二提交不了,抛异常回滚,所以不会发生脏写。

方案二:独立事务业务二执行时加 @GlobalLock注解

全局事务 很重。

因此,在不需要全局事务、而又需要检查全局锁避免脏读脏写的场景,可以使用@GlobalLock注解实现隔离的功能,@GlobalLock是一个更加轻量的操作。

与 @GlobalTransactional注解效果类似,只不过 业务二不需要开启全局事务,只在本地事务提交前,检查全局锁是否存在。 如果存在,就抛出异常,从而本地事务回滚。

@GlobalTransactional注解 开启全局事务是一个比较重的操作,需要向 TC 发起开启全局事务等 RPC 过程,而@GlobalLock注解只会在执行过程中查询全局锁是否存在,不会去开启全局事务,

方案三:业务二执行时加 @GlobalLock 注解 + select for update语句

如果独立事务希望最终能够 提交, 在发现全局锁的过程中, 独立事务希望等待和重试,则可以使用下面的方案:

加 @GlobalLock 注解 + select for update语句

如果加了select for update语句,则会在 update 前检查全局锁是否存在,只有当全局锁释放之后,业务二才能开始执行 updateA 操作。

加select for update语句会在执行 SQL 前检查全局锁是否存在,只有当全局锁完成之后,才能继续执行 SQL,这样就彻底防止了脏读+脏写, 也能保护 独立事务不会 直接回滚。

所以@GlobalLock 注解 加 select for update 也有个好处,就是可以重试。

此面试题,收录于尼恩编著 《Seata 学习圣经》,PDF 全文可以找尼恩获取。

说在最后:有问题找老架构取经

以上的内容,如果大家能对答如流,如数家珍,基本上 面试官会被你 震惊到、吸引到。

最终,让面试官爱到 “不能自已、口水直流”。offer, 也就来了。

在面试之前,建议大家系统化的刷一波 5000页《尼恩Java面试宝典PDF》,里边有大量的大厂真题、面试难题、架构难题。很多小伙伴刷完后, 吊打面试官, 大厂横着走。

在刷题过程中,如果有啥问题,大家可以来 找 40岁老架构师尼恩交流。

另外,如果没有面试机会,可以找尼恩来改简历、做帮扶。

遇到职业难题,找老架构取经, 可以省去太多的折腾,省去太多的弯路。

尼恩指导了大量的小伙伴上岸,前段时间,刚指导一个40岁+被裁小伙伴,拿到了一个年薪100W的offer。

狠狠卷,实现 “offer自由” 很容易的, 前段时间一个武汉的跟着尼恩卷了2年的小伙伴, 在极度严寒/痛苦被裁的环境下, offer拿到手软, 实现真正的 “offer自由” 。

尼恩技术圣经系列PDF

  • 《NIO圣经:一次穿透NIO、Selector、Epoll底层原理》
  • 《Docker圣经:大白话说Docker底层原理,6W字实现Docker自由》
  • 《K8S学习圣经:大白话说K8S底层原理,14W字实现K8S自由》
  • 《SpringCloud Alibaba 学习圣经,10万字实现SpringCloud 自由》
  • 《大数据HBase学习圣经:一本书实现HBase学习自由》
  • 《大数据Flink学习圣经:一本书实现大数据Flink自由》
  • 《响应式圣经:10W字,实现Spring响应式编程自由》
  • 《Go学习圣经:Go语言实现高并发CRUD业务开发》

……完整版尼恩技术圣经PDF集群,请找尼恩领取

《尼恩 架构笔记》《尼恩高并发三部曲》《尼恩Java面试宝典》PDF,请到下面公号【技术自由圈】取↓↓↓

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/668490.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Transformer实战-系列教程3:Vision Transformer 源码解读1

🚩🚩🚩Transformer实战-系列教程总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Pycharm中进行 本篇文章配套的代码资源已经上传 Vision Transformer 源码解读1 Vision Transformer 源码解读2 Vision Transformer 源码解读3 Vis…

kubesphere部署k8s-v1.23.10

功能: 🕸 部署 Kubernetes 集群 🔗 Kubernetes 多集群管理 🤖 Kubernetes DevOps 🔎 云原生可观测性 🧩 基于 Istio 的微服务治理 💻 应用商店 💡 Kubernetes 边缘节点管理 &#x1…

latex论文写作遇到的问题

图一: 图二: 图三: 使用模版的时候将图一转为图二:在.tex文件开头导言部分加上: \usepackage{titletoc} \titlecontents{section}[0pt]{\addvspace{1.5pt}\filright\bf}{\contentspush{第\thecontentslabel\ 章\qu…

2024.2.4 awd总结

防御阶段 感觉打了几次awd,前面阶段还算比较熟练 1.ssh连接 靶机登录 修改密码 [root8 ~]# passwd Changing password for user root. New password: Retype new password: 2.xftp连接 备份网站源码 我觉得这步还是非常重要的,万一后面被删站。。…

【幻兽帕鲁】如何快速部署私人服务器

看了许多关于如何部署服务器的,大部分都是要买阿里云或者腾讯云的服务器并且至少四核以上才能保证流畅运行。 但是对于想搭建私服但又没有技术的小白,确实是有点难度了。购买云服务器后还要配置服务器,配置OpenVPN、PalServer,doc…

解锁亚马逊测评防关联新技术:亚马逊鲲鹏系统

在亚马逊测评的过程中,一直以来都存在着一些技术难题,特别是在模拟买家行为时需要考虑诸多因素,包括关键词搜索、IP地址切换以及防关联等。然而,最新的技术突破,亚马逊鲲鹏系统正是为了解决这些问题而诞生的。 首先&am…

No matching client found for package name ‘com.unity3d.player‘

2024年2月5日更新 下面的一系列操作最终可能都无用,大致这问题出现原因是我在Unity采用了Android方式接入Firebase,而Android接入实际上和Unity接入方式有配置上的不一样,我就是多做了几步操作如下。https://firebase.google.com/docs/androi…

【Java】Redis入门

1. Redis入门 1.1 Redis简介 Redis是一个基于内存的key-value结构数据库。Redis 是互联网技术领域使用最为广泛的存储中间件。 官网:https://redis.io 中文网:https://www.redis.net.cn/ key-value结构存储: 主要特点: 基于内…

docker复习笔记01(小滴课堂)安装+部署mysql

查看内核版本。 关闭防火墙: 查看docker版本: 下载阿里yum源: 再看一下yum版本都有哪些: 我们可以看的docker-ce了。 安装它: 设置docker服务开机启动: 更新日志文件: 启动docker: …

CSS写渐变边框线条

box-sizing: border-box; border-top: 1px solid; border-image: linear-gradient(to right, red, blue) 1;

STM32F407移植OpenHarmony笔记9

继上一篇笔记,已经完成liteos内核的基本功能适配。 今天尝试启动OHOS和XTS兼容性测试。 如何启动OHOS? OHOS系统初始化接口是OHOS_SystemInit(void),在内核初始化完成后,就能调用。 extern void OHOS_SystemInit(void); OHOS_Sys…

JupyterLab 更换内核 使用 conda 虚拟环境

未有conda虚拟环境default先创建环境 conda create -n default python3.8 ipykernel已有conda虚拟环境default激活后安装ipykernel conda activate defaultpip install ipykernel将虚拟环境写入 jupyter notebook 的 kernel 中 python -m ipykernel install --user --name 虚…

C语言小游戏:贪吃蛇(游戏开发的环境和功能介绍)

❀❀❀ 文章由不准备秃的大伟原创 ❀❀❀ ♪♪♪ 若有转载,请联系博主哦~ ♪♪♪ ❤❤❤ 致力学好编程的宝藏博主,代码兴国!❤❤❤ 生命不停,学习不止。铁汁们,我是大伟,欢迎来到大伟的游戏时间&#xff0c…

一次Kubernetes Pod内存异常导致的测试环境耗时异常问题排查过程

概述 在使用公司内部后台系统测试环境时发现一个请求加载慢的问题,简简单单的列表,查询MongoDB数据库,测试环境不过几百上千条数据而已,请求耗时居然高达5~6秒: 作为对比,生产环境的请求响应截图如下&…

【Java程序设计】【C00194】基于SSM的高校财务处理管理系统(论文+PPT)

基于SSM的高校财务处理管理系统(论文PPT) 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于ssm的高校从财务处理系统 本系统分为财务和管理员2个功能模块。 财务:财务登录高校财务处理系统后,能对首页、个人中心…

链表经典算法(+OJ刷题)

文章目录 前言一、移除链表元素二、链表的中间节点三.反转链表四.合并两个有序链表五.分割链表六.环形链表的约瑟夫问题总结 创作不易,点赞收藏一下呗!!! 前言 在上一节,我们介绍了单链表的增,删&#xff…

docker手动迁移镜像

1&#xff0c;将镜像保存在本地 docker save 镜像名称:版本号 > 镜像名称.tar 2&#xff0c;下载镜像 通过 ftp 工具或者命令&#xff0c;下载到本地 3&#xff0c;上传镜像到目标 docker 所在服务器 4&#xff0c;导入镜像 docker load < 镜像名称.tar

Electron实战(一):环境搭建/Hello World/打包exe

文章目录 Electron安装Node.jsNodeJs推荐配置开始Electron项目创建index.js文件创建src目录运行打包生成exe生成安装包踩坑 下一篇Electron实战(二)&#xff1a;将Node.js和UI能力&#xff08;app/BrowserWindow/dialog)等注入html Electron Electron是一个使用JavaScript, HT…

AI-数学-高中-22-tanx的图像与性质

原作者视频&#xff1a;三角函数】9tanx的图像与性质&#xff08;易中档&#xff09;_哔哩哔哩_bilibili 做题时注意先画图&#xff0c;再计算。

RabbitMQ(保姆级教程)

RabbitMQ学习 基础 1. 同步通信和异步通信 同步调用 下一步动作必须依赖上一步 异步调用 通知到位就行&#xff0c;不对消费者做强制要求&#xff0c;只要求最终一致性就行 2. MQ技术选项 消息先进先出&#xff0c;RabbitMQ默认有序 Erlang 是面向并发&#xff0c…