分布式事务简述

什么是事务?

通常给出的定义是数据库的执行逻辑单元。这句话感觉跟没说一样。
我们平时用到事务,主要是用到它的四个特性(ACID)。
我去看待问题的时候,通常会去问一些“傻”的问题:那为什么是这4个特性,不是其他的呢?或者为什么是4个,而不是3个或5个呢?
这4个特性被定义出来后,后续出来的数据库需要满足这4个特性,才可以说自己支持了事务。

什么叫分布式事务?

我们知道事务的作用范围是数据库,即一个事务内的数据库操作都是对同一个数据库进行的。
当一个“事务”内的数据库操作是对多个数据库进行的,这个“事务”就叫做分布式事务。

实际应用中通常情况下是以下两种情况:

  • 一个系统的某个操作涉及多个数据源。但又希望这个操作本身满足事务的特性,这种需求就是分布式事务的需求,满足这种需求的事务就叫分布式事务。

  • 同样地,在这个微服务盛行(烂大街)的年代,一个操作可能涉及很多个服务系统,每个服务有自己的数据源。但又希望这个操作本身满足事务的特性,这种也叫做分布式事务。

其实第一说法并不常见,因为按照微服务的单一职责原则来说,一个系统访问多个数据源还要保证事务性,要么你的数据库设计有问题,要么需要拆服务了。

如何实现分布式事务?

本质上有两种思想:

  • 引入一个事务协调者
    希望达到的效果是:由协调者协调多个事务,要提交大家一起提交,要回滚大家一起回滚。
  • TCC
    抛开数据库事务束缚,使用业务数据的状态来达到事务的特性。

这两个思想下面进行详细描述。

事务协调者

最早的分布式事务模型是 X/Open 国际联盟提出的 X/Open Distributed Transaction Processing(DTP)模型,也就是大家常说的 X/Open XA 协议,简称XA 协议。
即引入一个事务协调者,将对数据库的提交/回滚转交给协调者进行操作。


分布式事务

这个方案整体看起来还行。
但有一个问题:如果4.1提交失败,4.2提交成功。这个时候,我们怎么办?
4.1提交重试是一个办法,但如果一直重试失败怎么办?
这个时候,4.2已经提交成功,又不可能再回滚了。这个时候就数据不一致了,很严重。
对于应对这种情况,有人提出了2pc和3pc的思想。注意,这里强调一下,2pc/3pc是为了应对提交失败的情况的改进。

2pc

说得简单点,就是提交这个操作分为两步,先去prepare一下,每个数据源反馈一下,提交大概率会成功还是失败。如果成功,那么就都提交,如果有一个说大概率会失败,就回滚。


2pc
缺点:
  • 性能问题,在执行期间所有数据源都不能提交,资源锁定。
  • 单点,协调者成为单点。
  • 数据不一致,网络分区后,部分数据源收不到提交请求。
  • 网络分区后,由于部分数据源收不到提交/回滚请求,可能导致该数据库资源一直得不到释放的情况,引起资源的严重浪费。

3pc

在2pc的prepare和commit之间又加了一个cancommit阶段,并且加了超时机制。

  • 加了一个阶段的好处,将提交成功率的概率再次提升。因为concommit又做了一些undo日志的事情。
  • 超时机制的目的是对应应对2pc的第4个缺点。
    协调者的超时,即收不到参与者的ack,则认为是没有成功。
    参与者的超时,在cancommit和commit之间,一直没有收到commit,则自行提交,避免占用锁。
缺点

2pc的3个缺点仍然存在,其中因引入超时机制,参与者可自行提交。可能导致数据不一致现象更加突出。

XA优点

说一下XA的优点吧,
因为是参与者的操作依赖于本地事务,所以天然具有事务的一些特性。

XA缺点

性能资源问题
中心化问题
数据不一致问题

TCC

核心点在于,不依赖事务管理器,依靠业务逻辑的分解来完成。
说得简单点,XA会hold住各个本地事务不提交,TCC不会,通过业务逻辑分解来实现业务层面的事物特性。
TCC = try + confirm + cancel
即分布式事务参与者需要提供

  • try:完成所有的业务校验和大部分的逻辑处理。这个阶段几乎是要完成所有的业务处理的,只是会预留一些状态(表示中间状态)。后面的cc只是很薄的一层,理论上只是改一些状态就可以了。
  • confirm:提交。修改try阶段的落地数据状态。理论上是一定要成功的,就算一次不成功,重试也要成功。所以这个阶段一定要保证幂等。
  • cancel:取消也叫回滚。删除或修改try阶段的落地数据状态。同样的,理论上也必须保证成功。
分布式事务的发起者
image.png

分布式事务的框架实现粗略图。
发起者应用起本地事务,事务的开始调用分布式事务的框架进行开启一个分布式事务(注册两个事务同步器,如果本地事务提交/回滚,则调用分布式事务参与者的对应方法)。
然后发起者程序里,正常调用A和B,如果A和B失败,则需要回滚本地事务。而从触发框架的提交/回滚操作。

分布式事务补偿

虽然说分布式事务的参与者的两个CC方法,需要保证一定成功。
但这个世界不是完美的,一定会出现某个参与者的CC方法失败的情况,这个时候就需要一种分布式事务的补偿机制。
即分布式事务开启时需要记录该事务的状态,以及对应参与者的信息。
当提交成功后,方可删除,如果提交/回滚失败,则需要定时任务来进行重试。
这一步必不可少,公司实现生产中,很多依靠补偿机制来完成数据的一致性保障。

空回滚问题

在实际生产中,会遇到这类问题,作为一个分布式事务的参与者,先收到了cancel请求,然后再收到了try请求。
这种情况发生的概率还不小,这也是tcc的一种常见的异常情况。

  • 为什么会出现这种情况?
    发起者调用参与者时,由于网络原因或其他原因(积压),try请求一直没到参与者系统中。
    然后发起者此时认为参与者超时了,发起了cancel请求。
    所以无法保障try一定先于cancel,但可以保证try一定先于confirm(这个留给大家思考下原因)。
  • 造成的结果
    cancel到了之后,发现没有try,然后直接空处理。
    后续try来了后,处理成功,然后这个请求一直没有confirm/cancel了。导致一直处于事务的悬挂状态。
  • 解决办法
    • 分布式锁
      try来了后,加锁,完成后解锁。
      cancel来了后,加锁3分钟(如果try没完成会失败),完成后不解锁。
      此办法可解决cancel先来了,3分钟内try再来会直接失败掉,解决空回滚的问题。
    • 前置事务表(推荐)
      同样的道理。
      try来了后,插入P,完成后删除。
      cancel来了后,插入R(如果是P则失败),完成后不删除。
      cancel先来了,插入R,后续try来了后插入P失败,解决空回滚问题。

优点

不依赖事务管理器,所以不存在事务资源性能的问题。

缺点

  • 使得业务接口变得复杂。
    之前一个接口,现在需要提供3个接口。
  • 数据不一致
    cc的两个接口必须各个业务系统实现幂等和一定成功。如果业务系统打破了,就会造成数据不一致的现象。
  • 空回滚与悬挂问题

总结

这里主要说了两种分布式事务的理论:XA协议与TCC。
分析了两种理论的原理以及优缺点。
由于目前公司的分布式事务主要是TCC实现,所以对此比较熟悉。

这里也推荐大家
实际生产中,能不要用分布式事务的话,尽量不要用,会给系统带来太多的复杂性。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345

推荐阅读更多精彩内容