常见分布式事务解决方案
1、 seata 阿里分布式事务框架(首推AT)
2、消息队列(TCC) 3、 saga(Saga)
4、XA(XA)
他们有一个共同点,都是"两阶段(2PC)". “两阶段"是指完成整个分布式事务,划分成两个步骤完成。 实际上,这四种常见的分布式事劳解决方案,分别对应着分布式事务的四种模式:AT、TCC、Saga、XA; 四种分布式事务模式,都有各自的理论基础,分别在不同的时间被提出;每种模式都有它的适用场景,同样每个模式也都诞生有各自的代表产品;而这些代表产品,可能就是我们常见的(全局事务、基于可靠消息、最大努力通知、TCC).
分布式事务理论基础 解决分布式事务,也有相应的规范和协议。分布式事务相关的协议有2PC、3PC。 由于三阶段提交协议3PC非常难实现,目前市面主流的分布式事务解决方案都是2PC协议。这就是文章开始提及的常见分布式事务解决方案里面,那些列举的都有一个共同点"两阶段""的内在原因。 有些文章分析2PC时,几乎都会用TCC两阶段的例子,第一阶段try,第二阶段完成confim或cancel。其实2PC并不是专为实现TCC设计的,2PC具有普适性——协议一样的存在,目前绝大多数分布式解决方案都是以两阶段提交协议2PC为基础的。 TcC (Try-Confirm-Cancel)实际上是服务化的两阶段提交协议。
2PC两阶段提交协议: 2PC(两阶段提交,Two-Phase Commit)顾名思义,分为两个阶段:Prepare和commit
Prepare:提交事务请求
1.询问协调者向所有参与者发送事务请求,询问是否可执行事务操作,然后等待各个参与者的响应。 ⒉执行各个参与者接收到协调者事务请求后,执行事务操作(例如更新一个关系型数据库表中的记录),并将Undo和Redo信息记录事务日志中。 3响应如果参与者成功执行了事务并写入Undo和Redo信息,则向协调者饭回YES响应,否则返回NO响应。当然,参与者也可能宕机,从而不会返回响应。
正常提交事务:
1.commit请求协调者向所有参与者发送Commit请求。 2事务提交参与者收到Commit 请求后,执行事务提交,提交完成后释放事务执行期占用的所有资源。3.反馈结果参与者执行事务提交后向协调者发送Ack响应。 4.完成事务接收到所有参与者的Ack响应后,完成事务提交。
没办法保证100%事务成功率只能尽量保证事务成功率
中断事务 在执行Prepare 步骤过程中,如果某些参与者执行事务失败.宕机或与协调者之间的网络中断,那么协调者就无法收到所有参与者的VES响应,或者某个参与者返回了No响应此时,协调者就会进入回退流程,对事务进行回退。
1. rollback请求协调者向所有参与者发送 Rollback请求。 ⒉事务回滚参与者收到Rollback后,使用Prepare阶段的Undo日志执行事务回滚,完成后释放事务执行期占用的所有资源。
3.反馈结果参与者执行事务回滚后向协调者发送Ack响应, 4.中断事务接收到所有参与者的Ack响应后,完成事务中断。
2PC的问题 1.同步阻塞参与者在等待协调者的指令时,其实是在等待其他参与者的响应,在此过程中,参与者是无法进行其他操作的,也就是阻塞了其运行,倘若参与者与协调者之间网络异常导致参与者一直收不到协调者信息,那么会导致参与者一直阻塞下去。 2.单点在2PC中,一切请求都来自协调者,所以协调者的地位是至关重要的,如果协调者宕机,那么就会使参与者一直阻塞并一直占用事务资源. 如果协调者也是分布式,使用选主方式提供服务,那么在一个协调者挂掉后,可以选取另一个协调者继续后续的服务,可以解决单点问题,但是,新协调者无法知道上一个事务的全部状态信息(例如已等待Prepare响应的时长等),所以也无法顺利处理上一个事务。 3.数据不一致Comnit事务过程中Commit请求Rollack请求可能因为协调者宕机或协调者与参与者网络问题丢失,那么就导致了部分参与者没有收到Comit/Rollack请求,而其他参与者则正常收到执行了Commit/Rollback 操作,没有收到请求的参与者则继续阻塞。这时,参与者之间的数据就不再一致了。 当参与者执行CommirPalack后会向协调者发送Ack,然而协调者不论是否收到所有的参与者的Ack,该事务也不会再有其他补救措施了,协调者能做的也就是等待超时后像事务发起者返回一个“我不确定该事务是否成功"。 4.环境可靠性依赖协调者Prepare 请求发出后,等待响应,然而如果有参与者宕机或与协调者之间的网络中断,都会导致协调者无法收到所有参与者的响应,那么在2PC中,协调者会等待一定时间,然后超时后,会触发事务中断,在这个过程中,协调者和所有其他参与者都是出于阻塞的。这种机期对网络问题常见的现实环境来说太苛刻了。
AT模式(auto transcation) AT模式是一种无侵入的分布式事务解决方案。阿里seata框架,实现了该模式。 在AT模式下,用户只需关注自己的"业务SQL",用户的"业务SQL”作为一阶段,Seata框架会自动生成事务的二阶段提交和回滚操作。
AT模式如何做到对业务的无侵入∶ .一阶段: 在一阶段,Seata会拦截"M业务SQL”,首先解析$QL语义,找到业务SQL "要更新的业务数据,在业务数据被更新前,将其保存成before image",然后执行业务SaL"更新业务数据,在业务数据更新之后,再将其保存成after image"”,最后生成行锁。以上操作全部在一个数据库事务内完成,这样保证了一阶段操作的原子性。
.二阶段提交: 二阶段如果是提交的话,因为“业务SQL在一阶段已经提交至数据库,所以Seata框架只需将一阶段保存的快照数据和行锁删掉,完成数据清理即可.
.二阶段回滚: 二阶段如果是回滚的话,Seata就需要回滚一阶段已经执行的"业务SQL,还原业务数据。回滚方式便是用before image"还原业务数据;但在还原前要首先要校验脏写,对比"数据库当前业务数据"和"after image",如果两份数据完全一致就说明没有脏写,可以还原业务数据,如果不一致就说明有脏写,出现脏写就需要转人工处理。
TCC模式
优点:侵入性比较强,并且得自己实现相关事务控制逻辑
缺点:在整个过程基本没有锁,性能更强 TCC模式需要用户根据自己的业务场景实现 Try、Confim和Cancel三个操作;事务发起方在一阶段执行Ty方式,在二阶段提交执行Confim方法,二阶段回滚执行Cancel方法。
Seata
Server端存储模式(store.mode)支持三种: file:(默认)单机模式,全局事务会话信息内存中读写并持久化本地文件root.data,性能较高(默认)
db:(5.7+)高可用模式,全局事务会话信息通过db共享,相应性能差些。打开config/file.conf ? ? 修改mode="db ? ? ?修改数据库连接信息 (username\password)
? ? ?创建数据库 .redis: Seata-Server 1.3及以上版本支持,性能较高,存在事务信息丢失风险,请提前配置适合当前场景的redis持久化配置
|