分布式事务与Seata

分布式事务DTP模型

DTP模型是Distributed Transaction Processing的缩写,DTP是一套分布式事务的规范,不同的厂商针对此规范提供实现。DTP中包含AP、RM、TM三个角色,其中:

  • AP(Application Program):应用程序,就是我们使用分布式事务的应用;
  • RM(Resource Manager):资源管理器,表示参与分布式事务的资源,比如数据库,MQ等;
  • TM(Transaction Manager):事务管理器,是分布式事务的协调者。

它们之间的关系如下:

image

在DTP模型中,AP操作RM完成事务中的数据操作,比如数据库的更新等,在这些操作结束后,AP通过TX接口向TM发起提交事务或者回滚事务,TM通过XA协议向RMs提交或者回滚事务,XA通过两阶段提交的方式完成事务的提交或回滚。

DTP和XA的缺点:

  • 缺少事务补偿机制,2PC有数据不一致的风险,如果多个RM只有一部分提交成功,其它RM在提交事务时出现超时等错误,无法进行事务的补偿,会造成数据不一致
  • XA协议会导致资源的阻塞,在整个事务的过程中,RM资源会一直被事务持有,直到事务提交或回滚
  • 性能非常低
  • 并不是所有资源都支持XA协议,mysql5.7以前的版本对XA的支持不太好

两阶段提交(2PC)

前面说过XA协议通过两阶段提交的方式做事务的提交或回滚,两阶段提交,即将事务的提交分为两个阶段:

  • 第一阶段:prepare阶段,用于向RM询问事务是否可提交,至于RM如何实现prepare则完全靠RM,比如记录redo和undo日志
  • 第二阶段:commit/rollback,如果所有RM的prepare执行后都表示可以提交,则依次commit,否则依次rollback

两阶段提交的示意图可表示如下:

image

如果有RM的prepare阶段失败,则需要回滚,示意图如下:

image

2PC的缺点:

  • 整个事务过程中,所有资源都是阻塞式持有
  • 性能差
  • 会有数据的不一致风险,当有部分资源提交成功部分不成功时,数据不一致
  • TM容易成为逻辑单点,当TM宕机,事务状态难以恢复

Seata对分布式事务的支持

image

这里先介绍三个概念:

  • 全局事务:表示一次分布式事务,由TM发起
  • 分支事务:每个RM都有一个事务,被称为分支事务
  • XID:全局事务的事务ID

Seata借鉴了DTP模型中的概念,并且自定义了TC(Transaction Coordinator)角色,实际上是将事务的协调者从TM中分享出来并独立部署,TC负责全局事务的提交和回滚,并对分支事务做补偿,使得即使事务提交过程各,部分分支事务成功部分失败,也能达到最终一致

Seata支持的分布式事务的模式

AT模式

AT模式是建立在数据库的ACID事务的基础上的,它提供的两阶段提交是对XA的两阶段提交的演进,效率上比XA好,但是整体开销还是偏大。AT模式的基础原理是在每个分支事务的数据库中记录事务的回滚日志,seata对事务的处理过程如下:

  • 开启全局事务,向TC获取事务ID

  • 依次执行分支事务

  • 开启分支事务

  • 通过解析sql的方式拿到sql的表、更新字段、条件等

  • 根据条件查询,获取到事务更新前的镜像

  • 执行更新

  • 再次查询,获取 到更新后的镜像

  • 通过后镜像生成redo log,插入到分支事务所在的库中

  • 提交分支事务前,先向TC注册分支事务,并获取操作的数据的id对应的全局锁,如果获取失败,全局锁被其它事务持有,则回滚

  • 提交分支事务,并向TC上报分支事务执行结果

  • 提交全局事务,释放全局锁

当事务需要回滚时,每个分支事务的DB中有redo log,RM通过redo log执行事务的回滚,但回滚时需要对数据进行判断,如果当前数据与redo log中的兵团镜像相同,则回滚,否则表示数据被事务外的操作修改了,需要根据配置策略做处理。AT模式下的两阶段提交行为如下:

  • 一阶段 prepare 行为:在本地事务中,一并提交业务数据更新和相应回滚日志记录。
  • 二阶段 commit 行为:马上成功结束,自动 异步批量清理回滚日志。
  • 二阶段 rollback 行为:通过回滚日志,自动 生成补偿操作,完成数据回滚

TCC模式

Seata支持TCC模式,TCC模式也是基于两阶段提交的,与AT模式不同的是,TCC不依赖数据库的ACID特性,而是依赖应用自定义的一阶段的prepare行为和二阶段的commit/rollback行为,TCC模式将事务从数据库层面提升到了应用服务层面。

在TCC模式中,分支事务需要实现prepare、commit和rollback三个方法,其示意图如下:

image

总体过程比较清晰:

  • TM开启全局事务,获取XID

  • 依次执行分支事务

  • 向TC注册分支事务

  • 执行事务的prepare阶段

  • 提交或者回滚全局事务,TC向每个RM发起commit或者rollback

TCC模式下,两阶段行为如下:

  • 一阶段 prepare 行为:调用 自定义 的 prepare 逻辑。
  • 二阶段 commit 行为:调用 自定义 的 commit 逻辑。
  • 二阶段 rollback 行为:调用 自定义 的 rollback 逻辑。

Saga模式

Saga模式是SEATA提供的长事务解决方案,在Saga模式中,业务流程中每个参与者都提交本地事务,当出现某一个参与者失败则补偿前面已经成功的参与者,一阶段正向服务和二阶段补偿服务都由业务开发实现。

说简单点,就是第一阶段,每个分支事务先自己提交,当需要回滚的时候,分支事务提供一个回滚的入口,对事务做逆向过程:

image

Saga模式有一定的优势:

  • 参与者可异步执行
  • 性能高,一阶段提交本地事务
  • 补偿服务易于实现

AT、TCC、Saga三种模式的比较

  • AT模式:

  • AT模式的性能低,有全局锁,一次分支事务多一次SQL解析和两次查询一次插入,成本比本地事务高得多,这些DB操作是实现回滚的代价

  • 全局锁有死锁的风险

  • 保证了隔离性,全局锁能实现读隔离和写隔离,详情可以阅读seata的文档

  • 基于本地数据库的ACID特性,代码改造代价低

  • TCC模式:

  • 代码改造代价大,需要将事务拆分成prepare+commit并提供rollback

  • 性能好,不会阻塞资源

  • 将两阶段由应用自身定义,可达到较高的隔离性

  • Saga模式:

  • 代码改造代价比TCC模式小,但比AT模式大,需要提供回滚补偿接口

  • 性能好,第一阶段就提交了分支事务

  • 没有隔离性

AT、TCC、Saga三种模式,是在性能、改造成本、隔离性三者之间做权衡和取舍,AT选择了隔离性和低改造成本,TCC选择了性能和隔离性,Saga选择了性能和低改造成本,如下图所示:

image

基于事务消息的分布式事务方案

还可选择使用RocketMQ的事务消息来实现分布式事务。

优点:

  • 实现简单,改造成本小
  • 性能高,没有全局锁,也没有两阶段的开销

同样有缺点和限制:

  • 没有隔离性的支持
  • 弱一致,对于库存扣减类场景不适用
  • 事务消息一旦提交,全局无法回滚

如果采用事务消息实现分布式事务,需要有其它方案规避其缺点,这里不做描述。

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

推荐阅读更多精彩内容