支付宝分布式事务介绍
分布式事务的实现方法

分布式事务的实现方法
分布式事务的实现方法有多种,以下是其中几种常见的方案:
1. 两阶段提交(XA 方案):事务管理器先询问各个数据库是否准备好了,每个要操作的数据库都回复事务管理器ok,那么就正式提交事务。
2. TCC方案:TCC的全称是:Try、Confirm、Cancel。
Try阶段是对各个服务的资源做检测以及对资源进行锁定或者预留;Confirm阶段是在各个服务中执行实际的操作;Cancel阶段是如果任何一个服务的业务方法执行出错,那么就需要进行补偿,即执行已经执行成功的业务逻辑的回滚操作。
一般来说,支付、交易等需要严格保证资金正确性的场景会使用TCC方案。
3. 可靠消息最终一致性方案:通过消息队列将分布式事务中的操作进行异步解耦,从而实现最终的一致性。
这种方式能够处理大量并发操作,但是可能会存在数据不一致的风险。
4. 最大努力通知方案:通过最大努力的方式将通知发送给其他服务,以实现分布式事务的一致性。
这种方式简单易行,但是可能会因为网络问题或者服务不可用等原因导致通知失败。
5. SAGA方案:SAGA是一种基于事务的分布式事务处理模型,它将一个分布式事务视为一系列本地事务的组合。
每个本地事务在一个单独的节点上执行,并且通过消息传递进行通信。
SAGA能够保证全局事务的最终一致性,同时具有较好的容错性和可恢复性。
以上是分布式事务的几种常见实现方案,每种方案都有其优缺点,需要根据具体的业务场景和需求来选择适合的方案。
分布式事务的实现的方式与原理

分布式事务的实现的方式与原理分布式事务是指跨多个数据库、服务或系统的事务操作,确保这些操作要么全部成功要么全部失败的能力。
实现分布式事务通常涉及多种方式和技术,以下是几种常见的实现方式和原理:1. 两阶段提交协议(2PC):•原理: 由协调者 (Coordinator)和参与者 (Participant)组成。
在第一阶段,协调者询问参与者是否准备好提交事务;在第二阶段,协调者根据参与者的反馈决定是提交事务还是中止事务。
•优点: 确保了事务的原子性,但存在单点故障和阻塞问题。
2. 三阶段提交协议(3PC):•原理: 在两阶段提交的基础上增加了预提交阶段,以解决部分阻塞和单点故障的问题。
•优点: 减少了两阶段提交的一些阻塞和单点故障问题,但仍然可能存在阻塞和同步问题。
3. 补偿事务(Compensating Transactions):•原理: 在分布式环境下,通过执行与主事务相反的操作来回滚事务,即执行补偿操作来消除主事务的影响。
•优点: 可以处理长时间的分布式事务,但需要在系统中实现相应的补偿逻辑。
4. 分布式事务管理器(Distributed Transaction Manager):•原理: 使用分布式事务管理器 (例如Java的JTA或Microsoft 的DTC)来实现分布式事务,管理多个数据库或服务之间的事务性操作。
•优点: 提供了方便的API和工具,简化了分布式事务的管理和实现。
5. 分布式数据库(Distributed Databases):•原理: 使用分布式数据库系统,将数据分散存储在不同的节点上,通过数据分片和复制来处理分布式事务。
•优点: 数据分布在不同节点上,可以提高系统的扩展性和容错性。
以上方法各有优劣,并根据具体情况选择合适的方式来实现分布式事务。
这些方法都旨在解决分布式环境下数据一致性和事务性的问题,但每种方法都有其适用场景和局限性。
选择合适的方式需要考虑系统的需求、性能、可靠性和复杂性等因素。
分布式事务的概念与原理

分布式事务的概念与原理好的,那我们就开始聊聊分布式事务的概念与原理吧。
你有没有想过,在一个超级大的公司里,不同部门就像不同的小系统一样,它们有时候得一起干一件大事儿。
比如说举办一场超级盛大的公司年会,这就像是一个事务。
场地部门要负责找场地,餐饮部门要准备美食,表演部门要安排节目,这些部门的工作就像是分布式系统里不同的服务或者数据库操作。
如果场地找好了,但是餐饮没准备好,那这个年会肯定就乱套了,就像分布式事务里一部分成功一部分失败是不行的。
那什么是分布式事务呢?简单来说,就是在分布式系统里,涉及到多个节点(就像刚刚说的不同部门)操作的时候,要保证这些操作要么全都成功,要么全都失败,就像年会要么完美举办,要么干脆不办。
现在来说说它的原理吧。
想象一下,你和你的小伙伴们一起做一个超级大的拼图,这个拼图就是一个分布式事务。
你们每个人负责一部分拼图块(每个拼图块就像是一个子事务)。
在开始拼之前,得有个计划,这就好比是分布式事务里的事务协调器。
首先,事务协调器会告诉每个小伙伴(各个子事务):“嘿,我们要开始拼这个大拼图啦,大家准备好。
”这就是事务开始的信号。
然后呢,每个小伙伴就开始做自己的那部分拼图工作。
在这个过程中,小伙伴们(子事务)会时不时地向事务协调器报告自己的进展情况,就像“我已经拼好这块儿了”或者“我这块儿有点问题”。
这个过程就像是子事务的执行和状态反馈。
假如有个小伙伴发现自己那块拼图块丢了(子事务执行失败),那他就会赶紧告诉事务协调器。
事务协调器收到这个消息后,就会像个超级英雄一样,它得通知其他小伙伴:“哎呀,咱们这个拼图出问题了,大家先停一下,把已经拼好的部分拆了吧,我们重新来。
”这就是回滚操作。
所有小伙伴就得按照协调器说的,把自己拼好的部分还原,保证整个拼图(分布式事务)回到最初的状态。
如果每个小伙伴都顺利地完成了自己的拼图块(所有子事务都执行成功),那事务协调器就会开心地宣布:“太棒了,我们的大拼图完成啦!”这就表示分布式事务成功提交了。
支付宝分布式事务设计草案

支付宝分布式事务设计草案支付宝是一款非常成功的移动支付平台,每天处理着大量的交易。
为了保障用户的资金安全和交易的准确性,支付宝需要设计一种分布式事务方案。
本文将提出一个草案,对支付宝分布式事务的设计进行讨论。
一、背景支付宝是一个分布式系统,由多个服务组成,每个服务都有着自己的数据库。
在用户进行交易时,涉及到多个服务的操作,比如扣款、存款等。
为了保障数据的一致性,支付宝需要设计一种支持分布式事务的方案。
二、问题支付宝面临的主要问题是如何保障多个服务之间数据的一致性和交易的准确性。
在出现故障或者异常情况时,需要能够回滚事务,保障用户的资金安全。
三、解决方案1.引入分布式事务协调器:支付宝可以引入一个分布式事务协调器,负责协调多个服务之间的事务操作。
协调器可以记录事务的状态,并在需要时进行回滚操作。
2.使用可靠消息队列:支付宝可以使用可靠消息队列来实现分布式事务。
在用户发起交易时,将相关操作封装成一个消息发送到消息队列中,各个服务监听消息队列,并执行相关操作。
当所有服务都执行成功后,消息消费成功,事务提交。
如果出现故障或者异常情况,消息未被消费成功,可以进行回滚操作。
3. 采用TCC(Try-Confirm-Cancel)模式:TCC是一种分布式事务模式,通过预留资源、确认执行和取消操作来保障事务的一致性。
支付宝可以在每个服务上实现TCC模式,进行事务的预测、确认和取消操作,从而保证多个服务之间的数据一致性。
4.引入分布式锁:支付宝可以引入分布式锁来保障事务的并发控制。
在每个服务上加锁,保证同一时刻只有一个事务能够操作数据。
当事务执行完毕后释放锁,让其他事务能够继续操作。
5. 引入Saga模式:Saga是一种分布式事务模式,通过一系列本地事务来实现全局事务。
支付宝可以在每个服务上实现Saga模式,每个本地事务执行成功后,发送消息通知下一个服务执行事务。
如果出现故障或者异常情况,可以通过回滚前面的事务来保障数据的一致性。
支付宝分布式事务设计草案

支付宝分布式事务架构设计草案1背景介绍为了应对快速变化的市场需求、持续增长的业务量,支付宝系统需要基于SOA进行构建与改造,以应对系统规模和复杂性的挑战,更好地进行企业内与企业间的协作。
基于SOA图景,整个支付宝系统会拆分成一系列独立开发、自包含、自主运行的业务服务,并将这些服务通过各种机制灵活地组装成最终用户所需要的产品与解决方案。
支付宝系统将会有类似下图所示的SOA模型:在SOA的系统架构下,一次业务请求将会跨越多个服务。
我们举一个使用红包+余额进行交易付款的例子来说明。
在多个服务协同完成一次业务时,由于业务约束(如红包不符合使用条件、账户余额不足等)、系统故障(如网络或系统超时或中断、数据库约束不满足等),都可能造成服务处理过程在任何一步无法继续,使数据处于不一致的状态,产生严重的业务后果。
传统的基于数据库本地事务的解决方案只能保障单个服务的一次处理具备原子性、隔离性、一致性与持久性,但无法保障多个分布服务间处理的一致性。
因此,我们必须建立一套分布式服务处理之间的协调机制,保障分布式服务处理的原子性、隔离性、一致性与持久性。
2基本原理2.1两阶段提交协议(2PC)传统的分布式事务处理是基于两阶段提交协议的。
两阶段提交协议的原理如下图所示:成功的两阶段提交(2PC)示例失败的两阶段提交(2PC)示例从上图可见,两阶段提交协议的关键在于“准备”操作。
分布式事务协调者在第一阶段通过对所有的分布式事务参与者请求“准备”操作,达成关于分布式事务一致性的共识。
分布式事务参与者在准备阶段必须完成所有的约束检查、并且确保后续提交或放弃时所需要的数据已持久化。
在第二队段,分布式事务协调者根据之前达到的提交或放弃的共识,请求所有的分布式事务参与者完成相应的操作。
2.2最末参与者优化(LPO)两阶段提交协议要求分布式事务参与者实现一个特别的“准备”操作,无论在资源管理器(如数据库)还是在业务服务中实现该操作都存在效率与复杂性的挑战。
分布式事务的处理流程

分布式事务的处理流程分布式事务是指在多个数据源之间执行的事务,它要求所有数据源执行的操作都应满足ACID(原子性、一致性、隔离性和持久性)特性。
为了保证分布式事务的正常处理,需要实现一套事务处理流程,具体包括以下几个步骤:1、发起事务:分布式事务由发起者发起,发起者在发起事务之前需要准备好相关数据,记录事务参与者列表,收集所有参与者的处理结果,并添加事务处理指令到每个参与者;2、分发事务:将发起者收集的事务处理指令分发给参与者进行处理;3、等待执行结果:等待参与者返回处理结果,发起者在收集到所有参与者的处理结果后,根据收集到的处理结果,判断事务的最终处理结果,并通过提交或者回滚来完成事务处理;4、数据提交或回滚:根据事务最终处理结果,完成数据的提交或回滚执行;5、状态清理:在事务处理完成后,需要对事务状态做一个清理,防止影响下次事务处理;以上五步就是一般分布式事务处理流程,根据事务复杂度,发起者可以增加或减少一些步骤来满足不同的事务处理要求。
实际中,发起者和参与者使用相同的分布式事务框架来完成分布式事务处理流程,该框架通过一个调度器来管理事务和数据,比如2PC或3PC,两种不同的调度方式可以用来完成分布式事务的处理。
2PC协议是最常用的分布式事务处理协议,它将分布式事务处理过程分为两步:首先由调度器获取事务参与者的处理结果,然后将结果发送给参与者,根据所有参与者的处理结果,调度器再进行提交或者回滚的操作。
在这一步骤中,调度器需要维护每一个参与者的状态,保证可靠性,并在出现异常的情况下,切换到另一种事务处理类型,以免发生数据丢失。
3PC协议是2PC协议的增强版,它在2PC的基础上,增加了一个watchdog,用于处理2PC中存在的问题,比如调度器宕机,导致无法提交或回滚等情况,watchdog可以在出现故障时,把事务回滚到一致性状态,从而保证数据的安全,使得整个分布式事务处理过程更加安全可靠。
无论是2PC还是3PC,都是一种复杂的分布式事务处理流程,它们都需要维护一个状态,确保分布式事务的正确性,它们的优点是简单易用,缺点是容错性低,无法满足大部分场景的高可用性要求。
分布式事务解决方案3--本地消息表(事务最终一致方案)

分布式事务解决⽅案3--本地消息表(事务最终⼀致⽅案)⼀、本地消息表原理1、本地消息表⽅案介绍本地消息表的最终⼀致⽅案采⽤BASE原理,保证事务最终⼀致在⼀致性⽅⾯,允许⼀段时间内的不⼀致,但最终会⼀致。
在实际系统中,要根据具体情况,判断是否采⽤。
(有些场景对⼀致性要求较⾼,谨慎使⽤)2、本地消息表的使⽤场景基于本地消息表的⽅案中,将本事务外操作,记录在消息表中其他事务,提供操作接⼝定时任务轮询本地消息表,将未执⾏的消息发送给操作接⼝。
操作接⼝处理成功,返回成功标识,处理失败,返回失败标识。
定时任务接到标识,更新消息的状态定时任务按照⼀定的周期反复执⾏对于屡次失败的消息,可以设置最⼤失败次数超过最⼤失败次数的消息,不进⾏接⼝调⽤等待⼈⼯处理例如使⽤⽀付宝的⽀付场景,系统⽣成订单,⽀付宝系统⽀付成功后,调⽤我们系统提供的回调接⼝,回调接⼝更新订单状态为已⽀付。
回调通知执⾏失败,⽀付宝会过⼀段时间再次调⽤。
3、本地消息表架构图4、优缺点优点:避免了分布式事务,实现了最终⼀致性缺点:注意重试时的幂等性操作⼆、本地消息表数据库设计整体⼯程复⽤前⾯的my-tcc-demo1、两台数据库 134和129。
user_134 创建⽀付消息表payment_msg, user_129数据库创建订单表t_order2、使⽤MyBatis-generator ⽣成数据库映射⽂件,⽣成后的结构如下图所⽰三、⽀付接⼝1、创建⽀付服务PaymentService@Servicepublic class PaymentService {@Resourceprivate AccountAMapper accountAMapper;@Resourceprivate PaymentMsgMapper paymentMsgMapper;/*** ⽀付接⼝* @param userId ⽤户Id* @param orderId 订单Id* @param amount ⽀付⾦额* @return 0: 成功; 1:⽤户不存在 2:余额不⾜*/public int payment(int userId, int orderId, BigDecimal amount){//⽀付操作AccountA accountA = accountAMapper.selectByPrimaryKey(userId);if(accountA == null){return 1;}if(accountA.getBalance().compareTo(amount) < 0){return 2;}accountA.setBalance(accountA.getBalance().subtract(amount));accountAMapper.updateByPrimaryKey(accountA);PaymentMsg paymentMsg = new PaymentMsg();paymentMsg.setOrderId(orderId);paymentMsg.setStatus(0); //未发送paymentMsg.setFailCnt(0); //失败次数paymentMsg.setCreateTime(new Date());paymentMsg.setCreateUser(userId);paymentMsg.setUpdateTime(new Date());paymentMsg.setUpdateUser(userId);paymentMsgMapper.insertSelective(paymentMsg);return 0;}}2、创建Controller层@RestControllerpublic class PaymentController {@Autowiredprivate PaymentService paymentService;//localhost:8080/payment?userId=1&orderId=10010&amount=200@RequestMapping("payment")public String payment(int userId, int orderId, BigDecimal amount){int result = paymentService.payment(userId, orderId,amount);return "⽀付结果:" + result;}}3、调⽤接⼝localhost:8080/payment?userId=1&orderId=10010&amount=200查看表。
分布式事务:蚂蚁金服核心金融场景下的演进

分布式事务:蚂蚁金服核心金融场景下的演进展开全文本文根据尹博学在 2018 年 5 月 10 日在【第九届中国数据库技术大会】的现场演讲内容整理而成。
讲师介绍尹博学蚂蚁金服资深技术专家尹博学,蚂蚁金服资深技术专家,目前负责数据中间件技术方向。
此前在百度负责数据库内核及集群技术方向。
在分布式事务、数据库高性能/ 高可靠架构、数据库内核等领域有较为深入的研究和丰富的工程实践。
随着互联网技术快速发展,数据规模增大,分布式系统越来越普及,采用分布式数据库或者跨多个数据库的应用在中大规模企业普遍存在,而由于网络、机器等不可靠因素,数据不一致问题很容易出现。
而对金融业务来说,它们面向互联网进行变革时,除了一致性要求外,对高可用、高可扩展性也有极高的要求。
这是金融级分布式系统的最大挑战之一。
在蚂蚁金服核心系统提出微服务化时,曾遇到了非常大的技术难题。
首先是在服务拆分以后,面临跨服务的一致性问题; 其次,支付宝当时的峰值交易量已经非常高了,在解决一致性问题的同时,还需要兼顾性能。
然而,在当时最常见的还是基于XA 协议的分布式事务解决方案,虽然该方案能够实现跨服务一致性,但是在热点数据的处理上,却不能满足性能需求。
因此,蚂蚁金服微服务化过程中急需一种即能保证一致性,又能保证高性能的方案。
当时经过一系列调研和讨论,最终选择了以 BASE 最终一致性思想为基础,在业务层实现两阶段提交的TCC 分布式事务解决方案,该方案既能保证跨服务的最终一致,又能通过业务灵活加锁的方式大幅减少资源层加锁时间,高效处理热点问题。
随着蚂蚁金服业务不断丰富,业务逻辑越来越复杂,同时蚂蚁金融云上客户也越来越多,他们对分布式事务解决方案也不只是追求极限性能,也对接入便捷性、实时一致性有了要求。
近日于北京举行的 2018 DTCC 中国数据库技术大会上,蚂蚁金服数据中间件负责人尹博学分享了蚂蚁金服在分布式事务技术方向上全系列技术方案与产品:TCC、FMT、XA 三种各有侧重各有优势的方案。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
}
});
}
} else if (StringUtil.equals(InstructionStatusEnum.PRE_ACCREDITED.getCode(), data.getStatus())) { logger.warn("成功解释业务活动状态[businessType=" + businessType + ";businessId="+ businessId + "]:未执行。"); return BusinessActivityStateResolver.NOT_DONE; } else if (StringUtil.equals(InstructionStatusEnum.SUBMIT_SETTLED.getCode(), data.getStatus())) { logger.warn("成功解释业务活动状态[businessType=" + businessType + ";businessId="+ businessId + "]:已执行。"); return BusinessActivityStateResolver.DONE; }else { logger.error("严重异常:支付指令数据状态不正常,当前状态:" + data.getStatus() + ";尝试解释业务活动状态[businessType=" + businessType+ "; businessId=" + businessId + "]时。"); return BusinessActivityStateResolver.UNKNOWN; } } catch (Exception e) { logger.warn("警告:数据库异常;尝试解释业务活动状态[businessType=" + businessType+ ";businessId=" + businessId + "]时。", e); return BusinessActivityStateResolver.UNKNOWN; } }else { logger.error("严重异常:无需进行业务活动解释的类型;尝试解释业务活动状态[businessType=" + businessType+ ";businessId=" + businessId + "]时。"); return BusinessActivityStateResolver.UNKNOWN; }
/ /
21:31
APБайду номын сангаас
日志 锁
完成会话
复 习
全局事务(DTP模型)
全局事务 事务由全局事务管理 器全局管理 事务管理器 管理全局事务状态与 参与的资源,协同资 源的一致提交/回滚 TX协议 应用或应用服务器与 事务管理器的接口 XA协议 全局事务管理器与资 源管理器的接口
5 5
应用/应用框架/应用服务器 AP 开 始 全 局 事 务 1.
C2 B3
• • • •
Atomicity(原子性) Consistency(一致性) Isolation(隔离性) Durability(持久性)
难点:
A5
• 高度并发 • 资源分布 • 大时间跨度
1
2
3 4 操作时间
5
21:31
3
复 习
开始会话 应 用 应 用 服 务 器 应 用 框 架
本地事务
6
OK OK
OK
OK
OK OK
4.
2.
3.
NO
OK
6
回 顾
网关未独立前:一条龙
iwallet
网银处理逻辑 账务处理逻辑 交易处理逻辑
持久操作1
持久操作2
持久操作3
持久操作4
主 库
提交/回滚本地事务
21:31 7 7
回 顾 bankgw
网银处理逻辑 账务处理逻辑
网关独立部署 iwallet
通 知
交易处理逻辑
logger.error("严重异常:支付指令数据不存在;尝试解释业务活动状态[businessType=" + businessType+ ";businessId=" + businessId + "]时。"); return BusinessActivityStateResolver.UNKNOWN;
logger.error(...);
} } catch (Exception e) { logger.error(...);
、 status.setRollbackOnly(); //显式回滚
}
});
}
status.setRollbackOnly(); //显式回滚 } return transResult;
持久操作2
持久操作1
主 库
支 付 库 提交/回滚嵌套分布事务
账 务 库
21:31
11
集 成
适用场景
基本原则
业务活动中包括账务参与者的 只要操作账务,必须使用分布式事务,支付宝系统特有 账务是作为默认参与者存在的 多个业务活动参与者之间必须保持语义状态一致性的 可选,对于非实时类业务,可使用高可靠的ESB消息完成一致性
账务处理逻辑
持久操作2 持久操作1 持久操作3 持久操作4
主 库 提交/回滚本地事务
21:31
提交/回滚本地事务
8
回 顾 bankgw
网银处理逻辑
交易服务化进程 trade
通 知
账务处理逻辑
交易处理逻辑
持久操作2 持久操作1 持久操作4
iwallet
账务处理逻辑 持久操作4
主 库 提交/回滚本地事务
21:31
持久操作3
提交/回滚本地事务 提交/回滚本地事务
9
回 顾
bankgw
账务服务化
确保通知
trade
acctrans
持久操作1 持久操作2 持久操作3
主 库
提交/回滚分布事务
账 务 库
持久操作4
提交/回滚分布事务
21:31 10
回 顾
mipgw
双峰插云
paycore acctrans
持久操作3
21:31
16
集 成
启动业务活动
businessActivityControlService.start(...); ②
业务活动的启动有两种方式: 带参数: businessType + businessId businessType:业务活动类别,每个类别的前 三位对应到某个业务类型,后三位是对此业务类 型的具体操作;如002代表提现,而002001代表 提现申请中的冻结部分 businessId:业务数据的ID或可以唯一定位到 业务数据的key 无参数:系统自动分配业务活动ID(全局唯一) 推荐使用以businessType + businessId方式启动业 务活动: 根据businessType 可准确定位至业务及操作,便利 了对故障的分析、排查、以及出错系统的快速定位 利用businessType的前三位,分布式任务恢复程序 可以找到正确的回查实现者 通过businessId,可以迅速的定位到具体的业务数 据、日志信息等
21:31
13
集 成
示例代码
public AccountTransResult foo() { return (AccountTransResult)transactionTemplate ①.execute(new TransactionCallback() { //确保在本地事务块中 public Object doInTransaction(TransactionStatus status) { AccountTransResult transResult =null; try { businessActivityControlService.start(...); ② //启动业务活动 transResult = accountTransFacade.freezeAccountBalance(null,...); //请求账务交易处理 //判断账务前置处理结果 if (transResult.isSuccess()) { localBizHandle(); //本地业务逻辑处理 localDBHandle(); //本地数据持久处理 } else {
21:31
15
集 成
回查实现示例代码
/* (non-Javadoc) * @see com.alipay.sofa.platform.xts.bacs.spi.BusinessActivityStateResolver#isDone(ng.String, ng.String) */ public int isDone(String businessType, String businessId) { if (StringUtil.isBlank(businessType) || StringUtil.isBlank(businessId)) {
本地事务 事务由资源管理器(如 DBMS)本地管理 优点 • 支持严格的ACID属性 • 可靠 • 高效 • 状态可以只在资源管理器 中维护 • 应用编程模型简单(在框 架或平台的支持) 局限 • 不具备分布事务处理能力 • 隔离的最小单位由资源管 理器决定,如数据库中的 一条记录