.Net Core with 微服务 - 分布式事务 - 2PC、3PC

最近比较忙,好久没更新了。这次我们来聊一聊分布式事务。
在微服务体系下,我们的应用被分割成多个服务,每个服务都配置一个数据库。如果我们的服务划分的不够完美,那么为了完成业务会出现非常多的跨库事务。即使按照 DDD 的原则来切分服务还是免不了有的业务场景需要多个业务同时提交成功或者同时回滚的场景。比如会员使用积分下订单这个场景,那么会员服务的积分扣减需要跟订单下单成功同时完成。如果下单成功,但是扣减积分接口失败,那么就会造成数据的不一致性。这个时候我们就需要使用分布式事务来保证数据的一致性。由于分布式事务要介绍的东西比较多,这一篇只介绍 2PC、3PC 的基本概念,所以 .net 相关的内容大概也只会出现在标题上一次,笑哭。

什么是 2PC

2PC 既 Two-phase Commit ,中文翻译为二阶段提交。2PC 要求每个事务的参与方都把一个事务抽象成2个阶段。下面大概分析下 2PC 事务的流程。
首先提出2个概念:

  1. 参与方 分布式事务中所有需要同时进入事务的业务方。

  2. 协调器
    分布式环境下为了对多个事务参与方进行统一的调度管理,我们需要一个调度器。

阶段一

事务开始后,协调器下达事务开始的命令,每个参与方收到命令后开始执行准备阶段(Prepare phase),所谓准备阶段就是执行本地事物,这个时候资源被锁定,但是不进行提交。如果这个阶段没有发生异常,那么参与方会通知协调器“执行成功”。如果某个参与方在这个阶段失败了,那么同样通知协调器“执行失败”,协调器会给所有参与方发布回滚的命令。参与方在收到“回滚”命令后执行回滚操作。

阶段二

如果所有的参与方在阶段一全部响应成功,那么协调器就会给每个参与方发布执行提交操作的命令。参与方收到提交命令后开始尝试进行事务提交。如果事务提交成功,参与方会通知协调器“提交成功”。待到所有的参与方全部回复“提交成功”,那么本次事务成功执行。

到这里我们可以看到 2PC 模型跟数据库的事务模型是高度契合的,所以 2PC 经常用来把多个数据库事物包装成一个分布式事务的场景。事实上大多数数据库如:oracle,mysql等自己已经实现了基于XA协议的2PC 事务。

2PC 的问题

  1. 在一阶段,假设参与方A执行事务成功并通知了协调器,参与方B执行失败,由于网络的问题一直无法上报给协调器,这个时候会造成参与方A事务一直是等待提交状态,阻塞整个业务。这个时候就需要引入超时机制,在一定时间内没收到协调器的指令后直接回滚事务。

  2. 在一阶段,假设参与方A执行事务成功并通知了协调器,参与方B执行成功,由于网络的问题一直无法上报给协调器,这个时候会造成参与方A、参与方B事务一直是等待提交状态,阻塞整个业务。这个时候不光在参与方A一侧需要引入超时机制,在参与方B同样需要进入超时机制来自动回滚事务。

  3. 在二阶段,如果参与方A提交成功,参与方B因为某些原因提交失败,或者是服务器宕机或者是网络原因B一致没有收到提交的指令,这个时候就会造成数据不一致,这种情况 2PC 几乎没有补偿能力,只能依靠后期手动修复数据。

  4. 如果协调器在一阶段中间挂了,那么跟以上1、2情况类似,需要通过超时机制来补偿。

  5. 如果协调器在二阶段中间挂了,比如只给参与方A发送了提交请求,那么就会造成以上问题3类似的问题,造成数据不一致。

  6. 2PC 因为依赖数据库本地事务,我们知道事务一旦开启就会阻塞后面的业务执行。所以该方法在并发高的情况下会有比较大的性能问题。而且他所阻塞的时间远远高于单机事务,因为它所耗的时间取决于执行时间最长的那个参与方所执行的事务。

3PC

由于 2PC 的众多问题,又有人发明了 3PC 事务。
3PC 事务是对 2PC 的一次改进:

  1. 首先引入了超时机制避免事务长时间阻塞。

  2. 3PC 在 2PC 的 Prepare phase 阶段之前又加入了一个阶段叫做 CanCommit 阶段。现在3个阶段分别是:CanCommit、PreCommit、DoCommit 。后两个阶段大致可以映射到 2PC 的一阶段跟二阶段。那么CanCommit 阶段是干嘛的呢?CanCommit 只是一次预检,协调器先问一下各个参与者是否可以进行事务,同时也校验一下当前的网络是否正常,参与者服务器有没有宕机。经过这一次校验后,至少可以比 2PC 安全一点,减少因为当前网络故障服务宕机带来的故障的概率。但是 3PC 任然无法完全解决问题,在 DoCommit 命令发布后,依然有可能部分参与者提交成功,部分失败,2PC 数据不一致的问题 3PC 依然无法避免。

总结

以上简单介绍了 2PC、3PC 分布式事务的原理。我们可以看到 2PC 在理想情况下是可以保证数据一致性的。但是在复杂的生产环境下服务器宕机、网络故障的情况时有发生,最终导致数据的不一致,并且 2PC 的性能也差强人意。3PC 虽然改进了 2PC 的一些缺点,但是仍然没有解决掉最致命的数据不一致的问题、以及性能的问题。所以 2PC、3PC 并不是分布式事务的首选方案。那么下期我们将继续这个话题,继续介绍 TCC 分布式事务。

相关文章

NET Core with 微服务 - 什么是微服务
.Net Core with 微服务 - 架构图
.Net Core with 微服务 - Ocelot 网关
.Net Core with 微服务 - Consul 注册中心
.Net Core with 微服务 - Seq 日志聚合
.Net Core with 微服务 - Elastic APM
.Net Core with 微服务 - Consul 配置中心
.Net Core with 微服务 - Polly 熔断降级

关注我的公众号一起玩转技术

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

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

相关文章

写给还在大学的兄弟姐妹

看到软件专业毕业生之一个月攻略 这篇文章之后,忽然想起了自己两个多月前找工作时的写的一篇文章,便拿出来与大家分享。 这仅是个人的一些看法,不正确之处还请各位指出,有砖尽管拍。 基础很重要 许多企业招聘,要求大学…

2019优质公众号大盘点,果断收藏了慢慢看吧 ~

全世界只有3.14 % 的人关注了青少年数学之旅又到年底了啦,也到了一年一度的年底盘点时间。那么2019年,又有哪些优质公众号崭露头角呢?本期将为您盘点几个优质公众号,总有一个刷屏过你的朋友圈!长按二维码,选…

让未备案的网站先飙起来

让未备案的网站先飙起来作者:田逸(sery163.com)国人在技术方面的创新能力不怎么样,但是在设置障碍,折腾自己人的方面的创造性却登峰造极,比如网站备案。要备案也没什么问题,毕竟大家都是老老实实…

TDengine和DolphinDB哪个更好,哈哈哈哈,闲来无聊分析了一下。

#拥抱开源—涛思数据TDengine有奖征稿# TDengine是专为时序数据设计的,针对的是物联网、工业互联网、IT运维场景。这些场景是不需要特殊的查询函数的,更关心的是写入速度、查询速度。而且这些场景下,也需要一些其他数据库不具备的功能&#…

技术总监谈好的程序员如何写代码

要判断一个程序员是不是好的程序员,主要看他写的代码,因为程序员最重要的事是写代码。 即便不去理解代码的意图,只要看一眼,好的程序员写的代码与差的程序员写的代码基本上就可以看出来。好的程序员写的代码,整洁而规范…

记一次 .NET 某WMS仓储打单系统 内存暴涨分析

一:背景 1. 讲故事七月中旬有一位朋友加wx求助,他的程序在生产上跑着跑着内存就飙起来了,貌似没有回头的趋势,询问如何解决,截图如下:和这位朋友聊下来,感觉像是自己在小县城当了个小老板&#…

C语言面试题之华为篇2(答案全)

C语言面试题之华为篇(答案全) (1)什么是预编译,何时需要预编译: 答案: 1、总是使用不经常改动的大型代码体。 2、程序由多个模块组成,所有模块都使用一组标准的包含文件和相同的编…

一分钟读懂一个数学时代,看完不跪算我输!

▲ 点击查看上帝说,要有光,于是便有了光。而香农说,要有熵,于是信息化时代正式拉开帷幕。克劳德艾尔伍德香农(Claude Elwood Shannon)被尊称为“信息论之父”。不管你是否知道他,是如何看待他…

秋招面试我去了拼多多,直接被问JVMGC底层原理和算法,我吊打面试官

JVM 常用参数设置积累 # 堆的初始值,默认物理内存的1/64 -Xms: # 堆的最大值,默认物理内存的1/4 -Xmx: # 年轻代大小「在整个堆内存大小确定的情况下,增大年轻代将会减小年老代,反之亦然。此值关系到JVM垃圾回收,对系…

php中使用exec,system等函数调用系统命令

2019独角兽企业重金招聘Python工程师标准>>> 注意:要想使用这二个函数php.ini中的安全模式必须关闭,要不然为了安全起见php是不让调用系统命令的。  先看一下php手册对这二个函数的解释:  exec --- 执行外部程式  语法 : string exec ( string com…

了解jQuery技巧来提高你的代码

jQuery之所以如此流行并被从大公司到个人博客的几乎每个人都广泛使用,是因为它上手和使用相当简单,而且为我们提供了一些人都不知道的相当棒的特性。我认为jQuery的大多数用户更趋向于使用jQuery插件来解决面临的难题,这通常是明智的选择。但…

Vista Dynamips模拟器安装

原因由于npf文件,缺少这个文件就不能获取网卡参数:解决1:安装Ethereal,在安装过程中勾选“Start WinPcap service "NPF" at startup”这一项.然后就可以获取网卡参数!有可能不行,没关系.解决2:输…

如何主动清空.NET数据库连接池?

一般我们的项目中会使用1到2个数据库连接配置,同程艺龙的数据库连接配置被收拢到统一的配置中心,由DBA统一维护,业务方通过某个配置字符串拿到的是开箱即用的Connection对象。DBA能在对业务方无侵入的情况下,给业务方切换备份数据…

Java面试会问的——数组、声明、初始化、冒泡、多维数组、稀疏数组

数组 数组时相同类型数据的有序集合数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成其中,每一个数据称作一个数组元素,每一个数组元素可以通过一个下标来访问它们。 数组声明创建 首先必须声明数组变量,才能在…

假如有人在今天炸了支付宝的存储服务器...

全世界只有3.14 % 的人关注了青少年数学之旅今天在知乎看到了一个问题《假如有人把支付宝存储服务器炸了(物理炸),大众在支付宝里的钱是不是就都没有了呢?》外行人问题。网站都是有服务器的,服务器都是有实体的。那么支…

Android STL PORT

ndk中包含了stl对应的库,在$(NKD_HOME)/sources/cxx-stl/stlport/stlport 有关Android NDK的C STL开发相关总结如下: 从Android NDK r5开始支持了STL Port,在这个版本开始就可以使用部分STL库的功能了,比如说vector、map,string摆脱c下面容易…

Cookie全解

1. Cookie 可以存储哪些值 在 Cookie 中只能存储个人可识别信息. 个人可识别信息是指可以用来识别或联系用户的信息. 例如用户的姓名, 电子邮件, 家庭住址等. 必须强调的是, 这些可识别信息必须是非机密或重要信息. 2. 使用 Cookie 对象保存和读取客户端信息. 要存储一个 Cooki…

C# 10 完整特性介绍

前言开头防杠:.NET 的基础库、语言、运行时团队从来都是相互独立各自更新的,.NET 6 在基础库、运行时上同样做了非常多的改进,不过本文仅仅介绍语言部分。距离上次介绍 C# 10 的特性已经有一段时间了,伴随着 .NET 6 的开发进入尾声…

代码格式

2019独角兽企业重金招聘Python工程师标准>>> 1.参考:JavaScript程序编码规范 转载于:https://my.oschina.net/u/1791074/blog/283578

94年出生,6篇SCI,一作发Science,你还不放下手上玩的泥巴

全世界只有3.14 % 的人关注了 青少年数学之旅 2019年9月27日,国际顶尖期刊《科学》(Science)杂志在线以全文Article的形式发表了北京航空航天大学材料科学与工程学院赵立东教授课题组在热电材料研究上取得的新进展,北京航空航天大…