前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何利用事务消息实现分布式事务?

如何利用事务消息实现分布式事务?

作者头像
王小明_HIT
发布2020-05-25 23:36:44
1.7K0
发布2020-05-25 23:36:44
举报
文章被收录于专栏:程序员奇点程序员奇点

如何利用事务消息实现分布式事务

一说起事务,容易联想到数据库。我们日常使用事务的场景,绝大部分都是在操作数据库的时候。像 MySQL、Oracle这些主流的关系型数据库,也都提供了完整的事务实现。

那消息队列为什么也需要事务呢?

很多场景下,往往是一个模块往另外一个模块发消息的,往往需要另外一个系统接收到消息后更新数据,消息队列中的 “事务”,主要解决的消息生产者与消费者之间的数据一致性问题

栗子

电商购物,用户将商品添加到购物车,然后几个商品一起下单,最后支付,完成购物流程,这过程在订单系统创建订单后,发送西峡县给购物车系统,将已下单的商品从购物车中删除,但是购物车删除已下单商品这个步骤,并不是用户下单支付主要流程的必须步骤,因此使用消息队列来异步清理购物车是更加合理的设计。

业务场景

订单系统

订单系统,主要做了两件事:

  1. 在订单库中插入一条订单数据,创建订单。
  2. 发消息给消息队列,消息中的内容是刚创建的订单。
购物车系统

购物车系统其实也主要做两件事:

  1. 用户将商品添加购物车时,购物车系统中新增一条商品数据。
  2. 购物车系统收到了订单创建成功消息,清理已生成订单的商品数据。

这样就有一个需要解决的问题,需要保证订单库和购物车这两个库数据一致性。需要保证购物车系统状态是一致的,要么都成功,要么都失败,不允许一个成功一个失败的状态。

事务的4个属性

事务必须具有原子性,一致性,隔离性,持久性,也称为 ACID 特性。

  1. 原子性

原子性,指的是一个事务操作不可分割,要么成功,要么失败,不能有一半成功,一半失败的情况。

  1. 一致性

一致性,是指这些数据在事务执行完成这个时间点之前,读到的一定是更新前的数据,之后读到的一定更新后的数据,不应该存在一个时刻,让用户读到更新过程中的数据。

  1. 隔离型

隔离性,是指一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用数据对正进行的其他事务是隔离的,并发执行的各个事务之间不能相互干扰。

  1. 持久性

持久性,是指一个事务一旦完成事务,后续的其他操作和故障不会对事务的结果产生任何影响。

什么是分布式事务?

分布式事务就是要在分布式系统中的实现事务。在分布式系统中,在保证可用性和不严重牺性能的前提下,光是要实现数据的一致性就已经非常困难了,所以出现了很多“残血版”的一致性,比如顺序一致性、最终一致性等等。

CAP 原理

CAP 原理,是指分布式系统中,Consistency(一致性),Availability(可用性),Partion tolerance(分区容错性),三者不可兼得。

  1. 一致性(C)

在分布式系统中所有的数据备份,同一个时刻是同样的。

  1. 可用性(A)

在集群中一部分节点故障,集群整体是否还能响应客户端的读写请求。

  1. 分区容错性 (P)

以实际效果而言,分区相当于对通讯的实现要求,系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作 在 C 和 A 之间做出选择。

如何实现分布式事务?

实现分布式事务有 2PC(TWO-phase Commit 也叫量阶段提交),TCC(Try-Confirm-Cancel) 和事务消息。

消息事务机制--异步确保机制

两阶段提交

两阶段提交保障了分布式事务的原子性:即所有节点要么全做,要么全部做,所谓的两个阶段:第一个阶段:准备阶段;第二阶段:提交阶段。

两阶段提交

1,准备阶段

事务协调者给每个参与者(资源管理器)发送 PrePare 消息,每个参与者要么直接返回失败(如权限验证失败),要么在本地执行事务,写本地的 redo 和 undo 日志,但是不提交。

  1. 提交阶段

如果协调者收到的参与者的失败消息或者超时,直接给每个参与者发送回滚(Rollback)消息,否则,发送提交(Commit); 参与者根据协调者提交或者回滚操作,释放所有事物处理过程中的锁资源。

RocketMQ 中的分布式事务实现

RocketMQ 中的事务实现中,增加了事务反查的机制来解决时序消息提交失败的问题,如果 Producer 在提交或者会馆事务消息时发生网络异常,RocketMQ 的 Broker 没有收到提交或者回滚的请求,Broker 会定期去 Producer 上反查这个事务对应的本地事务的状态,然后根据反查结果决定提交或者回滚这个事务。

为了支持这个事务反查机制,我们的业务代码需要实现一个反查本地事务状态的接口,告知 RocketMQ 本地事务是 成功还是失败的。

举个例子,订单系统 根据消息中的订单ID ,在订单库中查询这个订单是否存在即可,如果订单存在则返回成功,否则返回失败, RocketMQ 会自动根据事务反查的结果提交或者回滚事务。

RocketMQ事务

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-05-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员奇点 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 如何利用事务消息实现分布式事务
    • 那消息队列为什么也需要事务呢?
      • 栗子
        • 事务的4个属性
          • 什么是分布式事务?
            • CAP 原理
            • 如何实现分布式事务?
          • RocketMQ 中的分布式事务实现
          相关产品与服务
          消息队列 CMQ 版
          消息队列 CMQ 版(TDMQ for CMQ,简称 TDMQ CMQ 版)是一款分布式高可用的消息队列服务,它能够提供可靠的,基于消息的异步通信机制,能够将分布式部署的不同应用(或同一应用的不同组件)中的信息传递,存储在可靠有效的 CMQ 队列中,防止消息丢失。TDMQ CMQ 版支持多进程同时读写,收发互不干扰,无需各应用或组件始终处于运行状态。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档