基本概念
XA:XA是由X/Open组织提出的分布式事务的规范。XA规范主要定义了(全局)事务管理器(Transaction Manager)和(局部)资源管理器(Resource Manager,如数据库)之间的接口。
JTA:作为java平台上事务规范JTA(Java Transaction API)也定义了对XA事务的支持,实际上,JTA是基于XA架构上建模的
原理:https://www.ibm.com/developerworks/cn/java/j-lo-jta/
概念:https://baike.baidu.com/item/XA?fr=aladdin
ACID:https://bingoex.github.io/2015/08/30/database-acid/
数据库隔离:https://bingoex.github.io/2015/09/02/database-isolation/
思想
引入一个协调者来统领全局。之前的每个数据库节点是资源管理器(RM), 负责执行本地的资源操作. 协调者也叫事务管理器(TM), 负责跟RM交互, 指挥RM工作
2PC (2阶段提交)
1、准备阶段
TM接到一个客户端发起的事务请求, 向每个RM发送请求, 让RM开始准备执行事务.
RM接到请求后, 首先 锁定本地资源, 然后写各种日志(redo, undo), 再加上执行本地的资源操作.
这些工作如果执行成功, 向TM回复准备完毕(YES), 否则, 回复准备失败(NO)。
2、提交阶段
该阶段分成两种情况:M整理RM的回复, 如果都是YES, 那么TM向所有RM发送提交请求.
RM接到请求后, 执行本地的提交动作(写Binlog), 释放资源, 并把执行结果反馈给TM.
TM整理RM的回复, 如果有RM回复NO或者有RM超时没回复, 那么TM向所有RM发送回滚请求.
RM接到请求后, 执行本地的回滚动作(根据undo执行回滚), 释放资源, 并把执行结果反馈给TM.
缺点
1、几乎等同于整个2PC执行期间, 都独占资源, 阻塞了其他资源操作,性能极差。
2、如果某个RM收不到TM的下一步指示(出现网络问题等),就会不知所措,只能等待TM超时。
3PC (三阶段提交)
1、预备阶段
TM接到客户端发起的事务请求, 向所有RM发送预备请求.
RM接到请求后, 审视自身条件(做一些基本检查, 不锁资源, 也不做真正的资源操作), 看看是否有资格完成本次操作.
如果自认为可以, 返回YES, 否则返回NO.
2、准备阶段
这个阶段很像2PC的提交阶段,RM接到TM回复。
如果都是YES, 向所有RM发送准备请求.
如果回复中有NO或者超时没回复, TM向所有RM发送中断请求.
RM接到请求后,
如果是准备请求, 执行2PC中准备阶段的动作(锁资源, 写日志, 执行本地资源操作, 回复YES, 坐等TM下一个指令等).
如果是中断请求(或者超时还没收到TM请求), 执行事务中断动作, 回复NO.
3、提交阶段
该阶段分成两种情况:
1)TM整理RM的回复, 如果都是YES, 那么TM向所有RM发送提交请求.
RM接到请求后, 执行本地的提交动作(写Binlog), 释放资源, 并把执行结果反馈给TM.
如果RM没接到TM请求, 默认也执行提交.
2)TM整理RM的回复, 如果有RM回复NO或者有RM超时没回复, 那么TM向所有RM发送回滚请求.
RM接到请求后, 执行本地的回滚动作(根据undo执行回滚), 释放资源, 并把执行结果反馈给TM.
如果RM没接到TM请求, 默认也执行提交.
优点
1、增加一个环节, 第一阶段大家都同意后, 第二阶段才去锁资源, 最大限度降低 “白锁” 资源情况的发生概率.
2、在RM这边, 引入超时处理机制, 并规范RM变成”愣头青”时的行为.
针对二阶段, 当RM迟迟收不到TM消息时, 直接回复NO, 告诉TM我不玩了.
针对三阶段, 当RM迟迟收不到TM消息时, 默认提交.(之所以有这样的默认行为是基于下面考虑:如果都到了第三阶段, 说明所有RM和TM之前两个阶段的交互都很顺利, 没有出现任何问题, 而仅仅只是三阶段出现了网络超时等特殊问题, 可以忽略不计, 认为大家一起提交的概率极高)
结论
无论2PC, 还是3PC, 都无法完全解决数据一致性问题. 比如3PC中提交阶段, RM接受TM消息超时, 会默认提交, 但如果真的发生了小概率事件, 其他RM都接到了回滚消息, 那这个默认执行提交的RM就跟其他RM出现了数据不一致.为实现一致性只能依靠Paxos。
参考资料
https://coolshell.cn/articles/10910.html