本地消息事务表

1.核心思想

将分布式事务拆分成本地事务进行处理,通过在分布式事务主动发起方额外新建事务消息表,事务发起方把业务处理和记录事务消息在本地事务中完成,轮询事务消息表发送事务消息,事务被动方基于消息中间件消费事务消息表中的事务消息

2.流程步骤

  1. 事务主动方在同一个本地事务中处理业务和写消息表操作(消息表状态为待处理)
  2. 事务主动方通过消息中间件通知事务被动方处理事务(此过程需要加定时任务,扫描消息表内状态为待处理的消息,重新发送消息)
  3. 事务被动方收到消息,处理业务后,发送事务已处理的消息给事务主动方
  4. 事务主动方收到消息后,将该条事务消息状态更新为已处理

过程分析

  1. 假设步骤1 异常或宕机:消息跟业务处理的数据一起回滚了,啥事没发生
  2. 假设步骤2 消息发送失败或者消息丢失:有定时任务,定时扫描消息表重复发送消息(保证消息一定发送成功)
  3. 假设步骤3业务处理失败或者消息发送失败:业务数据会回滚(必要时需要人工介入),反馈消息丢失,会有步骤2的定时任务重复唤起
  4. 假设步骤4更新失败:数据会回滚,依旧依赖定时任务的重复执行 直至成功

注意事项

  1. 消息一定要带有唯一性事务ID
  2. 两边的消息处理一定要具备幂等性
  3. 一个事务涉及多个服务,就要有多个状态或者多条不同业务类型的消息
  4. 整个过程过于依赖主动方的定时任务,可视情况优化
  5. 上述过程保证了事务一定成功,如果某些场景允许回滚,步骤3处理失败也可以发起回滚消息,主动方收到消息回滚处理,并更新事务状态为已回滚即可,即无论是正向成功还是反向回滚,保持最终一致性即可 (该方案不太建议回滚处理,毕竟核心思想就是保证第一步业务成功,后续一定成功! 但是万事看业务场景嘛)

3.优缺点

优点: 简单实现,没有过度依赖中间件

缺点:

  • 与具体的业务场景绑定,耦合性强,不可公用
  • 消息数据与业务数据同库,占用业务系统资源
  • 业务系统在使用关系型数据库的情况下,消息服务性能会受到关系型数据库并发性能的局限
  • 每个事务入口的业务系统都需要有消息表

柔性事务,数据最终一致性,最大努力交付思想

Last Updated: