分布式事务介绍
基本事务的特性
这篇文章有概念介绍:分布式系统CAP理论初探
ACID
-
原子性(Atomicity):要么全部完成,要么全部失败
-
一致性(Consistency):事务开始和完成时,数据必须保持一致的状态,数据库的完整性约束没有被破坏。比如A给B转账,不论转账事务是否成功,两者存款的总额不变
-
隔离性(Isolation):多个事务并发访问时,事务之间是隔离的,一个事务不能影响到其他事务的结果 ,不能看到其他事务运行时中间某个时刻的数据。
-
持久性(Durability):事务完成后,该事务对数据库所作的更改便持久地保存在数据库中,并不会被回滚
2PC
在2PC协议中,需要一个中心化协调者节点coordinator和N个参与者节点partcipant
2PC出现单点问题的三种情况
1.协调者正常,参与者宕机
由于 协调者 无法收集到所有 参与者 的反馈,会陷入阻塞情况。
解决方案:引入超时机制,如果协调者在超过指定的时间还没有收到参与者的反馈,事务就失败,向所有节点发送终止事务请求。
2.协调者宕机,参与者正常
无论处于哪个阶段,由于协调者宕机,无法发送提交请求,所有处于执行了操作但是未提交状态的参与者都会陷入阻塞情况.
解决方案:引入协调者备份,同时协调者需记录操作日志.当检测到协调者宕机一段时间后,协调者备份取代协调者,并读取操作日志,向所有参与者询问状态。
3.协调者和参与者都宕机
- 3.1.发生在第一阶段: 因为第一阶段,所有参与者都没有真正执行commit,所以只需重新在剩余的参与者中重新选出一个协调者,新的协调者在重新执行第一阶段和第二阶段就可以了。
- 3.2.发生在第二阶段 并且 挂了的参与者在挂掉之前没有收到协调者的指令。这种情形下,新的协调者重新执行第一阶段和第二阶段操作。
- 3.3.发生在第二阶段 并且 有部分参与者已经执行完commit操作。就好比这里订单服务A和支付服务B都收到协调者 发送的commit信息,开始真正执行本地事务commit,但突发情况,Acommit成功,B确挂了。这个时候目前来讲数据是不一致的。虽然这个时候可以再通过手段让他和协调者通信,再想办法把数据搞成一致的,但是,这段时间内他的数据状态已经是不一致的了, 2PC 无法解决这个问题。
2PC之XA方案:国际开放标准组织定义分布式事务处理模型DTP(Distributed Transaction Processing):
- AP(Application Program):即应用程序,可以理解为使用 DTP 分布式事务的程序。
- RM(Resource Manager):即资源管理器,可以理解为事务的参与者,一般情况下是指一个数据库实例,通过资源管理器对该数据库进行控制,资源管理器控制着分支事务。
- TM(Transaction Manager):事务管理器,负责协调和管理事务,事务管理器控制着全局事务,管理事务生命周期,并协调各个 RM。全局事务是指分布式事务处理环境中,需要操作多个数据库共同完成一个工作,这个工作即是一个全局事务
3PC
相比于2PC的改动点
-
引入超时机制,同时在协调者和参与者中都引入超时机制
-
在第一阶段和第二阶段中插入一个准备阶段,保证了在最后提交阶段之前各参与节点的状态是一致的
-
CanCommit:协调者coordinator向全部参与者partcipant发送CanCommit命令,询问是否能够执行事务提交操做。若是所有响应YES则进入下一个阶段。
-
PreCommit:协调者向全部参与者发送PreCommit命令,询问是否能够进行事务的预提交操做,参与者接收到PreCommit请求后,如参与者成功的执行了事务操做,则返回Yes响应,进入最终commit阶段。一旦参与者中有向协调者发送了
No
响应,或因网络形成超时,协调者没有接到参与者的响应,协调者向全部参与者发送abort请求,参与者接受abort命令执行事务的中断。 -
DoCommit: 在前两个阶段中全部参与者的响应反馈均是YES后,协调者向参与者发送DoCommit命令正式提交事务,如协调者没有接收到参与者发送的ACK响应,会向全部参与者发送abort请求命令,执行事务的中断。
TCC
TCC:Try、Confirm、Cancel
TCC要求每个分支事务实现三个操作:预处理Try、确认Confirm、撤销Cancel。
Try操作做业务检查及资源预留,Confirm做业务确认操作,Cancel实现一个与Try相反的操作即回滚操作。
TM首先发起所有的分支事务的try操作,任何一个分支事务的try操作执行失败,TM将会发起所有分支事务的Cancel操作,若try操作全部成功,TM将会发起所有分支事务的Confirm操作,其中Confirm/Cancel操作若执行失败,TM会进行重试。
- Try 阶段是做业务检查(一致性)及资源预留(隔离),此阶段仅是一个初步操作,它和后续的Confirm一起才能真正构成一个完整的业务逻辑。
- Confirm 阶段是做确认提交,Try阶段所有分支事务执行成功后开始执行 Confirm。通常情况下,采用TCC则认为 Confirm阶段是不会出错的。即:只要Try成功,Confirm一定成功。若Confirm阶段真的出错了,需引入重试机制或人工处理。
- Cancel 阶段是在业务执行错误需要回滚的状态下执行分支事务的业务取消,预留资源释放。通常情况下,采用TCC则认为Cancel阶段也是一定成功的。若Cancel阶段真的出错了,需引入重试机制或人工处理。
Reference
- https://www.shangmayuan.com/a/3f60b75690d943d39a6b62fa.html
- https://www.jianshu.com/p/60a100eee74a
- https://zhuanlan.zhihu.com/p/376378186
- https://www.cnblogs.com/qdhxhz/p/11167025.html