分布式系统原理( 四 )


3.2 MQ 消息事务消息事务的原理是将两个事务通过消息中间件进行异步解耦 。

分布式系统原理

文章插图
 
image.png
从上面可以看出,消息事务一定要保证业务操作与消息发送的一致性,如果业务操作成功,这条消息也一定投递成功 。
消息事务依赖于消息中间件的事务消息,基于消息中间件第二阶段提交实现的,RocketMQ 就支持事务消息 。RabbitMQ也支持事务消息
执行流程:
  1. 发送 Prepare 消息到消息中间件 。
  2. 发送成功后,执行本地事务 。
  3. 如果事务执行成功,则 Commit,消息中间件将消息下发至消费端 。
  4. 如果事务执行失败,则回滚,消息中间件将这条 Prepare 消息删除 。
  5. 消费端接收到消息进行消费,如果消费失败,则不断重试 。
这种方案也是实现了最终一致性,对比本地消息表实现方案,不需要再建消息表,不再依赖本地数据库事务了,所以这种方案更适用于高并发的场景 。
3.3 最大努力通知最大努力通知相比前两种方案实现简单,适用于一些最终一致性要求较低的业务,比如支付通知,短信通知这种业务 。以支付通知为例,业务系统调用支付平台进行支付,支付平台进行支付,进行操作支付之后支付平台会尽量去通知业务系统支付操作是否成功,但是会有一个最大通知次数 。如果超过这个次数后还是通知失败,就不再通知,业务系统自行调用支付平台提供一个查询接口,供业务系统进行查询支付操作是否成功 。
分布式系统原理

文章插图
 
image.png
执行流程:
  1. 业务系统调用支付平台支付接口, 并在本地进行记录,支付状态为支付中 。
  2. 支付平台进行支付操作之后,无论成功还是失败,都需要给业务系统一个结果通知 。
  3. 如果通知一直失败则根据重试规则进行重试,达到最大通知次数后,不再通知 。
  4. 支付平台提供查询订单支付操作结果接口 。
  5. 业务系统根据一定业务规则去支付平台查询支付结果 。
这种方案也是实现了最终一致性 。
3.4 补偿事务 TCCTCC,Try-Confirm-Cancel 的简称,针对每个操作,都需要有一个其对应的确认和取消操作 。当操作成功时调用确认操作,当操作失败时调用取消操作,类似于二阶段提交,只不过是这里的提交和回滚是针对业务上的,所以基于 TCC 实现的分布式事务也可以看做是对业务的一种补偿机制 。
3.4.1 TCC 第三个阶段:
  • Try 阶段:对业务系统做检测及资源预留、冻结 。
  • Confirm 阶段:对业务系统做确认提交,Try 阶段执行成功并开始执行 Confirm 阶段时,默认 Confirm 阶段是不会出错的 。即:只要 Try 成功,Confirm 一定成功 。
  • Cancel 阶段:在业务执行错误,需要回滚的状态下执行的业务取消,预留资源释放 。
在 Try 阶段,是对业务系统进行检查及资源预览,比如订单和存储操作,需要检查库存剩余数量是否够用,并进行预留,预留操作的话就是新建一个可用库存数量字段,Try 阶段操作是对这个可用库存数量进行操作 。
3.4.2 TCC执行流程:步骤一(Try 阶段):订单系统将当前订单状态设置为支付中,库存系统校验当前剩余库存数量是否大于 2,然后将可用库存数量设置为库存剩余数量 -2,并且设置冻结库存为2
  • image.png
步骤二(Confirm 阶段):如果 Try 阶段执行成功,执行 Confirm 阶段,将订单状态修改为支付成功,库存剩余数量修改为可用库存数量 。
  • image.png
步骤三(Cancel 阶段):如果 Try 阶段执行失败,执行 Cancel 阶段,将订单状态修改为支付失败,可用库存数量修改为库存剩余数量 。
  • image.png

分布式系统原理

文章插图
 
image.png
3.4.3 基于 TCC 实现的分布式事务框架:ByteTCC,github.com/liuyangming tcc-transaction:github.com/changmingxi




推荐阅读