分布式事务-1 存储层(DB)解决方案
事务:包含一系列工作序列,有明确的开始和结束边界,事务内的工作序列要么全部执行成功,要么全部失败。
本地事务:就是事务开始边界和结束边界内的一系列工作序列都在本地单机上执行。
分布式事务:就是在分布式系统中执行的事务,由多个不同系统的本地事务组成。
事务特性:
事务具有 ACID 4个特性:
原子性(atomicity),一个事务是一个不可分割的工作单位,事务中包括的操作要么都做,要么都不做。
一致性(consistency),事务必须是从一个一致性状态变到另一个一致性状态。
隔离性(isolation),一个事务的执行不能被其他事务干扰,并发执行的各个事务之间不能互相干扰。
持久性(durability),事务一旦提交,数据的状态就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。
本地事务与分布式事务都要满足ACID4个特性。只是在一致性上,本地事务必须满足强一致性,分布式事务根据系统规模来选择强一致性还是最终一致性。
分布式事务一般有基于存储层(DB)和基于应用层的实现方式,本篇文章主要讲一下基于存储层(DB)的分布式事务实现方式,下一篇文章我们再来看一下基于应用层的分布式事务实现方式。
分布式事务-存储层(DB)解决方案:
在数据存储层,实现分布式事务主要就是基于XA规范的两阶段提交协议(2PC)和三阶段提交协议(3PC)。只要支持XA规范的数据存储层,就都可以参与基于XA规范的分布式事务。主流关系型数据库都支持XA规范。
XA规范:
AP(Application Program):应用程序,定义事务边界。
TM(Transaction Manager):事务管理器,管理全局事务,分配事务唯一ID,管理事务的提交、回滚等操作。
RM(Resource Manager):资源管理器,管理本地单机资源。
两阶段提交(2PC)协议:
两阶段提交包括:准备阶段、提交阶段。
准备阶段(第一阶段):
TM向所有RM发送事务内容,询问是否可以提交事务,并等待所有RM答复。
RM执行事务操作,将 undo 和 redo 信息记入事务日志中(但不提交事务)。
如RM执行成功,给TM反馈 yes,表示可以提交;如执行失败,给TM反馈 no,表示不可以提交。
如图:
提交阶段(第二阶段):
第一种情况:当所有RM都反馈 Yes,提交事务。
TM向所有RM发出正式提交事务的请求(commit 请求)。
RM执行 commit 请求,并释放整个事务期间占用的资源。
各RM向TM反馈 ack(应答)完成的消息。
TM收到所有RM反馈的 ack 消息后,完成事务提交。
如图:
第二种情况:当任何一个RM反馈 No,中断事务。
TM向所有RM发出回滚请求(rollback 请求)。
RM使用阶段 1 中的 undo 信息执行回滚操作,并释放整个事务期间占用的资源。
各RM向协调者反馈 ack 完成的消息。
TM收到所有RM反馈的 ack 消息后,完成事务中断。
如图:
2PC协议实现简单,但是存在如下几个缺点:
性能问题,即同步阻塞问题,RM占用本地事务资源,其他管理器访问同一事务资源时,需要阻塞等待。
可靠性问题,即TM存在单点故障问题,TM出现故障,则系统处于停滞状态,RM则一直锁定事务资源。
数据一致性问题,在提交阶段,如果发生局部网络问题,一部分RM收到了提交消息,另一部分RM没收到提交消息,那么就导致了节点之间的数据不一致。
三阶段提交(3PC)协议:
三阶段提交包括:准备阶段、预提交阶段、提交阶段。
3PC将2PC的提交阶段拆分成两个阶段,即预提交阶段和提交阶段。同时在TM和RM中都引入了超时机制。
准备阶段(第一阶段):
与2PC相似,参考2PC第一阶段。
预提交阶段(第二阶段):
第一种情况:准备阶段所有RM均反馈 yes,则RM预执行事务。
TM向所有RM发出 preCommit 请求,进入预提交阶段。
RM收到 preCommit 请求后,执行事务操作,将 undo 和 redo 信息记入事务日志中(但不提交事务)。
各RM向TM反馈 ack 响应或 no 响应,并等待最终指令。
如图:
第二种情况:准备阶段任何一个RM反馈 no,或者等待超时后TM没有收到所有RM的反馈,则中断事务。
TM向所有RM发出 abort 请求。
无论收到TM发出的 abort 请求,还是在等待TM的消息时出现超时,RM均会中断事务。
如图:
提交阶段(第三阶段):
第一种情况:预提交阶段所有RM均反馈 ack 响应,则执行真正的事务提交。
TM向所有RM发出 doCommit 请求。
RM收到 doCommit 请求后,会正式执行事务提交,并释放整个事务期间占用的资源。
各RM向TM反馈 ack 完成的消息。
TM收到所有RM反馈的 ack 消息后,完成事务提交。
如图:
第二种情况:预提交阶段任何一个RM反馈 no,或者等待超时后TM无法收到所有RM的反馈,则中断事务。
TM向所有RM发出 abort 请求。
RM使用准备阶段中的 undo 信息执行回滚操作,并释放整个事务期间占用的资源。
各RM向协调者反馈 ack 完成的消息。
TM收到所有RM反馈的 ack 消息后,完成事务中断。
如图:
3PC相较于2PC,增加一个预提交阶段,减少了状态不一致的概率;在TM和RM端都增加了超时机制,降低了阻塞范围。
当网络发生故障时,仍然不能解决数据一致性的问题。
总结:
存储层(DB)的分布式事务解决方案就是基于XA规范的两阶段提交和三阶段提交,属于数据的强一致性。由于存在同步阻塞、单点故障、网络出现问题时数据不一致,所以在实际项目中很少使用2PC或3PC。一般都会选择下一篇文章将要讲的,基于应用层的分布式事务解决方案。
下一篇文章《分布式事务-2 应用层解决方案》讲解基于TCC和基于消息的分布式事务解决方案。
https://github.com/Justin02180218?tab=repositories
鼓励一下,点个“在看”