分布式事务之2PC和3PC

在微服务的系统中,各个微服务的数据库都是分开的,所以事务不能交给MySQL去管理了,必须通过一些别的方式去完成。

2PC

2PC 是基于 XA 规范搞出来的一套分布式事务的理论,全称是 Two-Phase-Commitment-Protocol,两阶段提交协议。
先说下 XA 规范:

XA规范

有个叫 X/Open 的组织定义了分布式事务的模型,里面有如下角色:

  • AP:Application 应用程序 -> 整个系统
  • TM:Transaction Manager,事务管理器 -> 管理事务的组件
  • RM:Resource Manager,资源管理器 -> MySQL
  • CRM:Communication Resource Manager,通信资源管理器 -> 消息中间件

XA其实就是定义了TM个RM之间的接口规范,为了方便数据库一起回滚,MySQL也有实现,但实际中不好用

继续说回2PC

简单说

2PC 的第一阶段就是让各个数据库都先执行SQL,但不提交,等所有都正常执行,一起提交,或者异常之后一起回滚。

流程

按照1.1->1.2->1.3->2.1->2.2->2.3 的顺序执行


image

如果1.2或者1.3执行失败,那么正在执行的和执行过的都会回滚

问题

这样好像是解决了分布式事务的问题,但还是有一些问题。

  • 同步阻塞:数据库1需要等待整个事务执行完成才能继续
  • 单点故障:TM是单点故障,挂了就结束了,如果做双击热备,备份TM不知道哪些提交了或者执行了
  • 脑裂问题:如果因为网络问题,有些收到了commit,有些没收到,数据就会有问题了

为了解决上面出现的一些问题,其实主要是怕其中一些数据库挂了,或者因为网络问题导致没有成功,所以出现了3PC

3PC

全称是 Three-Phase-Commitment-Protocol,三阶段提交协议,其实主要解决第三个脑裂问题。
简单说就是比2PC多了一个check的步骤


image
  1. 第一阶段提交 canCommit,检查下数据库是不是都有问题
  2. 第二阶段开始执行,但不提交,和2PC的第一阶段一样
  3. 第二阶段都执行成功了,第三阶段就开始执行提交

如果这时候的commit 请求因为网络问题没有送达,或者二阶段数据库发给TM的执行成功的消息没有送达,因为一阶段已经确定数据库是正常的,所以这里收到通知很大程度的原因是网络故障,所以3PC引入了超时机制。

超时机制

如果数据库二阶段结束后过了一段时间没有收到 commit 消息,那么数据库就默认 TM 挂了,自己执行 commit。这样的话,就解决了如下问题:

  1. 不会因为事务一直占用资源;
  2. 对于单次事务,也不会担心TM挂了;
  3. 脑裂问题也解决了,没收到commit的数据库也会在超时时间到达后自动commit

问题

但其实还有问题,可能一阶段数据库是好的,后面挂了,TM并不知道,以为整个事务执行成功了。或者后面有数据库异常了,应该要回滚,但是异常没有通知到TM,或者TM挂了,别的数据库也会commit,数据就会有问题。只能说3PC解决了大部分问题,是一个较优的方案。

你可能感兴趣的:(分布式事务之2PC和3PC)