Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >分布式事务 ( DTS ) 你必须知道的事儿

分布式事务 ( DTS ) 你必须知道的事儿

作者头像
用户2991389
发布于 2018-09-05 04:26:16
发布于 2018-09-05 04:26:16
2.1K0
举报

转载个人原创微信版

文章摘要:原来大型分布式/微服务系统中解决数据一致性问题,居然是通过……

目前云计算大数据、互联网领域的大部分系统都采用了SOA、微服务化的架构。一个涉及端到端全链路的业务操作往往会由多个服务和数据库实例共同完成。因此,在一致性要求较高的业务场景中,如何保证多个服务之间RPC调用后的数据一致将成为关键点。

一、分布式系统/SOA/微服务架构的特点:

在大型分布式系统中要同时能够满足,分布式一致性(Consistency)、可用性(Availability)和分区容忍性(Partitiontolerance),是不存在的。在大多数情况下只能满足其中的2项,而实现系统的最终一致性(Base理论)。

(1)CAP特点:

a.一致性(Consistency):(同样数据在分布式系统的各个节点上都是一致的)

b.可用性(Availability):(所有在分布式系统活跃的节点都能够处理操作且能响应查询)

c.分区容忍性(Partition

Tolerance) :(如果出现了网络故障、一部分节点无法通信,但是系统仍能够工作)

(2)ACID特点:

a.原子性(Atomicity)

一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。

b.一致性(Consistency)

事务的一致性指的是在一个事务执行之前和执行之后数据库都必须处于一致性状态。如果事务成功地完成,那么系统中所有变化将正确地应用,系统处于有效状态。如果在事务中出现错误,那么系统中的所有变化将自动地回滚,系统返回到原始状态。

c.隔离性(Isolation)

指的是在并发环境中,当不同的事务同时操纵相同的数据时,每个事务都有各自的完整数据空间。由并发事务所做的修改必须与任何其他并发事务所做的修改隔离。事务查看数据更新时,数据所处的状态要么是另一事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看到中间状态的数据。

d.持久性(Durability)

指的是只要事务成功结束,它对数据库所做的更新就必须永久保存下来。即使发生系统崩溃,重新启动数据库系统后,数据库还能恢复到事务成功结束时的状态。

二、分布式事务的基本介绍

分布式事务服务(Distributed

Transaction Service,DTS)是一种分布式事务框架,用来确保在大规模分布式/微服务环境下端到端业务操作的最终一致性。

由CAP定理可知,任何大型的分布式系统/微服务在一致性、可用性和分区容忍这三点上只能保证其中的两点。由于在分布式系统中经常发生丢包、网络故障,分区容忍性是必须要满足的,同时为了兼顾高可用性,绝大部分系统都将强一致性需求转化成最终一致性的需求,并通过幂等机制保证了数据的最终一致性。

三、常用的分布式技术介绍

(1)本地消息表(经典的ebay模式)

该方案的核心思想在于分布式系统在处理任务时通过消息日志的方式来异步执行。消息日志可以存储至本地文本、数据库或消息队列,然后再通过业务规则定时任务或人工自动重试。以在线支付系统的跨行转账为例:

第一步,伪代码如下,对用户id为A的账户扣款1000元,通过本地事务将事务消息(包括本地事务id、支付账户、收款账户、金额、状态等)插入至消息表:

Begintransaction

update user_account set amount = amount - 1000where userId = 'A'

insert intotrans_message(xid,payAccount,recAccount,amount,status)values(uuid(),'A','B',1000,1);

endtransaction

commit;

第二步,通知对方用户id为B,增加1000元,通常通过消息MQ的方式发送异步消息,对方订阅并监听消息后自动触发转账的操作;这里为了保证幂等性,防止触发重复的转账操作,需要在执行转账操作方新增一个trans_recv_log表用来做幂等,在第二阶段收到消息后,通过判断trans_recv_log表来检测相关记录是否被执行,如果未被执行则会对B账户余额执行加1000元的操作,并会将该记录增加至trans_recv_log,事件结束后通过回调更新trans_message的状态值。

(2)消息中间件

a.非事务消息中间件

这里仍然以上面跨行转账为例,我们很难保证在扣款完成之后对MQ投递消息的操作就一定能成功。这样一致性似乎很难保证。以下伪代码说明了消息投递的异常:

try{

boolean result = dao.update(model);//更新数据库失败抛出异常

if(result){

mq.send(model);//如果MQ超时或者接收方处理失败,抛出异常

}

}catch(Exception ex){

rollback();//如果异常回滚

}

对于以上的运行情况主要有以下几种:

1.操作数据库成功,向MQ中投递消息也成功,该属于正常情况,一切都OK。

2.操作数据库失败,不会向MQ中投递消息了。

3.操作数据库成功,但是向MQ中投递消息时失败,向外抛出了异常,刚刚执行的更新数据库的操作将被回滚。

从上面分析的几种情况来看,基本上能确保,发送消息的可靠性。我们再来分析下消费者端的问题:

1.接收者取出消息后,消费者对应的业务操作要执行成功。如果业务执行失败,消息不能失效或者丢失。需要保证消息与业务操作一致。

2.尽量确保消息的幂等性。如果出现重复消息投递,能够进行幂等而不对业务产生影响。

b.支持事务的消息中间件

Apache开源的RocketMQ中间件能够支持一种事务消息机制,确保本地操作和发送消息的异步处理达到本地事务的结果一致。

第一阶段,RocketMQ在执行本地事务之前,会先发送一个Prepared消息,并且会持有这个消息的接口回查地址。

第二阶段,执行本地事物操作。

第三阶段,确认消息发送,通过第一阶段拿到的接口地址URL执行回查,并修改状态,如果本地事务成功,则修改状态为已提交,否则修改状态为已回滚。

其中,如果第三阶段的确认消息发送失败后,RocketMQ会有定时任务扫描集群中的事务消息,如果发现还是处于prepare状态的消息,它会向消息发送者确认本地事务是否已执行成功。RocketMQ会根据发送端设置的策略来决定是回滚还是继续发送确认消息。这样就保证了消息的发送与本地事务同时成功或同时失败。

再回到上面转账的例子,如果用户A的账户余额已经减少,且消息已经发送成功,作为消费者用户B开始消费这条消息,这个时候就会出现消费失败和消费超时两个问题,解决超时问题的思路就是一直重试,直到消费端消费消息成功,整个过程中有可能会出现消息重复的问题,就需要采用前面说的幂等方案来进行处理。

分布式事务—2PC协议

为了解决大型分布式/微服务系统中的一致性问题,业界比较流行的做法是采用比较著名的有二阶提交协议(2

Phase Commitment Protocol)和三阶提交协议(3

PhaseCommitment Protocol)。考虑到性能问题,三阶段提交协议目前较少被采用。本文也主要介绍二阶段协议。

2PC协议

二阶段提交协议是分布式系统中较为经典的处理数据一致性的解决方案。在大型的集群环境中,对于单体微服务本身而言虽然能够通过代码质量、Mock测试等方法来确保自身服务的可用性,但是无法能够保证其他服务的可用性。当一个全链路的端到端业务操作,常常会跨多个节点、多个应用,为了能够保证全局事务的ACID特性,需要引入一个协调组件(这里称之为TM)来控制所有服务参与者(这里称之为RM)的操作结果,根据所有参与者的反馈结果来决定整个分布式事务究竟是提交还是回滚的结果。

第一阶段:称为准备(prepare)阶段。事务协调者向各个服务应用发送prepare请求,服务应用在得到请求后做预处理操作,预处理可能是做预检查,也可能是把请求临时存储,可以理解为是一种试探性地提交。下面是一般的步骤:

a.事务协调者会问所有的参与者服务,是否可以提交操作。

b.各个参与者开始事务执行的准备工作:如资源上锁,预留资源,写回滚/重试的log。

c.参与者响应协调者,如果事务准备工作成功,则回应“可以提交”,否则回应拒绝提交。

第二阶段:称为提交(commit)/回滚(rollback)阶段。是指事务真正提交或者回滚的阶段。如果事务协调者发现事务参与者有一个在prepare阶段出现失败,则会要求所有的参与者进行回滚。如果协调者发现所有的参与者都prepare操作都是成功,那么他将向所有的参与者发出提交请求,这时所有参与者才会正式提交。由此保证了要求全部提交成功,要么全部失败。下面是具体步骤:

a.如果所有的参与者都回应“可以提交”,那么协调者向所有参与者发送“正式提交”的命令。参与者完成正式提交,并释放所有资源,然后回应“完成”,协调者收集各个服务的“完成”回应后结束事务。

b.如果有一个参与者回应“拒绝提交”,那么协调者向所有的参与者发送“回滚操作”,并释放所有的资源,然后回应“回滚完成”,协调者收集各个服务应用的“回滚”返回后,取消整体的分布式事务。

下图为二阶段的成功和失败示例图:

二阶段提交协议解决的是分布式系统/微服务架构中数据强一致性的问题,其原理简单,但缺点也是存在,主要缺点如下:

a.单点问题:协调者在整个二阶段中的作用非常重要,一旦部署协调者组件服务的节点出现不可用宕机情况,那么会影响整个分布式系统的正常运行。

b.同步阻塞:二阶段提交执行过程中,所有服务参与者需要服从协调者的统一调度,期间处于阻塞状态,会一定程度上影响整个系统的效率。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017.10.15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
5种分布式事务解决方案优缺点对比
分布式事务是企业集成中的一个技术难点,也是每一个分布式系统架构中都会涉及到的一个东西,特别是在微服务架构中,几乎可以说是无法避免。
Java_老男孩
2019/12/02
2.8K0
微服务架构中分布式事务实现方案如何取舍
针对分布式系统的特点,基于不同的一致性需求产生了不同的分布式事务解决方案,追求强一致的两阶段提交、追求最终一致性的柔性事务和事务消息等等。各种方案没有绝对的好坏,抛开具体场景我们无法评价,更无法能做出合理选择。在选择分布式事务方案时,需要我们充分了解各种解决方案的原理和设计初衷,再结合实际的业务场景,从而做出科学合理的选择。
玄姐谈AGI
2019/11/06
6930
微服务架构中分布式事务实现方案如何取舍
浅谈分布式事务
现今互联网界,分布式系统和微服务架构盛行。一个简单操作,在服务端非常可能是由多个服务和数据库实例协同完成的。在一致性要求较高的场景下,多个独立操作之间的一致性问题显得格外棘手。 基于水平扩容能力和成本考虑,传统的强一致的解决方案(e.g.单机事务)纷纷被抛弃。其理论依据就是响当当的CAP原理。往往为了可用性和分区容错性,忍痛放弃强一致支持,转而追求最终一致性。 分布式系统的特性 在分布式系统中,同时满足CAP定律中的一致性 Consistency、可用性 Availability和分区容错性 Partiti
CSDN技术头条
2018/02/13
8280
浅谈分布式事务
不就是分布式事务,这下彻底清楚了😎
大家好,我是老三,上次发文的时候还是上次发文的时候,这篇文章分享分布式事务,看完要是你们不懂,那一定是不明白。
三分恶
2021/09/26
6740
不就是分布式事务,这下彻底清楚了😎
分布式事务终极解决方案汇总
分布式事务这个话题,开发者们一定都不陌生。电商系统最容易出现分布式事务的处理,比如用户在电商平台购买一个商品,用户首先下单,然后平台要扣减库存。创建订单和库存的扣减一般都在不同的服务器上(微服务架构)。而用户购买到商品的行为,必须要下单和扣减库存都成功,才算这次的交易成功,反之则失败。
码神联盟
2019/12/26
7960
分布式事务之深入理解什么是2PC、3PC及TCC协议?
在上一篇文章《【分布式事务】基于RocketMQ搭建生产级消息集群?》中给大家介绍了基于RocketMQ如何搭建生产级消息集群。因为本系列文章最终的目的是介绍基于RocketMQ的事物消息来解决分布式系统中的数据一致性问题,所以先给大家率先介绍了RocketMQ消息集群的搭建。
用户5927304
2019/07/31
2.3K0
微服务架构下分布式事务解决方案
在微服务架构中,随着服务的逐步拆分,数据库私有已经成为共识,这也导致所面临的分布式事务问题成为微服务落地过程中一个非常难以逾越的障碍,但是目前尚没有一个完整通用的解决方案。
BUG弄潮儿
2021/03/04
1.1K0
分布式事务处理方案大 PK!
松哥最近正在录制 TienChin 项目视频~采用 Spring Boot+Vue3 技术栈,里边会涉及到各种好玩的技术,小伙伴们来和松哥一起做一个完成率超 90% 的项目,戳戳戳这里-->TienChin 项目配套视频来啦。 ---- 说好了写 TienChin 项目的,最近这个分布式事务算是一个支线任务吧,今天是最后一篇,松哥再来一个短篇和小伙伴们总结一下分布式事务。 首先先说一个大原则:分布式事务能不用就不要用,毕竟这个用起来还是有一些麻烦的。当然,不用和不会用可是两码事。 1. 分布式事务基础理论
江南一点雨
2022/06/13
3400
分布式事务处理方案大 PK!
顶级 top 分布式事务方案的选择
所谓的 XA 方案,即:两阶段提交,有一个事务管理器 的概念,负责协调多个数据库(资源管理器)的事务,事务管理器先问各个数据库准备好了吗?如果每个数据库都回 ok,那就正式提交事务,在各个数据库上执行操作;如果任何其中一个数据库回答不 ok,那么就回滚事务。这种分布式事务方案,比较适合单块应用里,跨多个库的分布式事务,而且因为严重依赖于数据库层面来搞定复杂的事务,效率很低,不适合高并发的场景。
芋道源码
2021/08/09
6590
分布式系统事务一致性
现今互联网界,分布式系统和微服务架构盛行。业界著名的CAP理论也告诉我们,在设计和实现一个分布式系统时,需要将数据一致性、系统可用性和分区容忍性放在一起考虑。
Java编程指南
2020/06/28
8090
分布式系统事务一致性
分布式事务
在分布式系统中,多个服务配合完成一个流程,不同服务执行结果不一定都成功,这时候就会产生问题。比如订单微服务和库存微服务,下单的同时订单微服务请求库存微服务减库存, 如果订单服务执行成功,但是库存服务执行失败没有扣减库存,那么就会出现超卖现象。
羽毛球初学者
2024/10/16
1180
saga分布式事务_本地事务和分布式事务
2PC,两阶段提交,将事务的提交过程分为资源准备和资源提交两个阶段,并且由事务协调者来协调所有事务参与者,如果准备阶段所有事务参与者都预留资源成功,则进行第二阶段的资源提交,否则事务协调者回滚资源。
全栈程序员站长
2022/10/05
2.7K0
saga分布式事务_本地事务和分布式事务
漫画:什么是分布式事务?
在一系列微服务系统当中,假如不存在分布式事务,会发生什么呢?让我们以互联网中常用的交易业务为例子:
小灰
2022/07/05
3580
漫画:什么是分布式事务?
分布式事务的实现方法及替代方案
图的上半是两阶段提交成功的演示, 下半是两阶段提交失败的演示. 关于两阶段提交网上有很多经典的讲解, 这里就不细说了
java思维导图
2018/07/26
1K0
分布式事务的实现方法及替代方案
分布式事务专题
完成某件事情,可能有多个参与者需要执行多个步骤,最终多个步骤要么全部成功,要么全部失败。
botkenni
2023/03/01
5580
分布式事务专题
分布式系统学习10:分布式事务
单体架构时,以本地事务为例,业务场景是下单场景,用户下单、创建订单、扣减库存这些操作都可以在一个数据库事务中完成。
卷福同学
2025/01/23
890
分布式系统事务一致性
现今互联网界,分布式系统和微服务架构盛行。业界著名的CAP理论也告诉我们,在设计和实现一个分布式系统时,需要将数据一致性、系统可用性和分区容忍性放在一起考虑。
Bug开发工程师
2019/03/07
5830
分布式系统事务一致性
分布式事务解决方案总结
数据库里的事务大家都不陌生,而在微服务架构中由于一个任务执行可能涉及多个微服务,要想在分布式系统实现事务 就要用到分布式事务了。
张云飞Vir
2021/07/16
4150
浅谈分布式事务
普通事务就是一般所说的数据库事务,大家对数据库事务应该都很了解,这里再简单介绍下。
lyb-geek
2018/07/26
4210
浅谈分布式事务
分布式事务
两阶段提交协议 Two Phase Commitment Protocol 涉及到两种角色
Java_慈祥
2024/08/06
1270
分布式事务
相关推荐
5种分布式事务解决方案优缺点对比
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档