java实现分布式事务的三种方案

Java分布式事务 事务发起方发送消息到消息队列:// 将消息发送到消息队列// ...事务消费方接收和处理消息:try {// 处理消息的业务逻辑// ...// 消息处理成功,确认消费// 消息处理失败,取消消费,进行补偿或重试// 确认消费成功,将消息标记为已处理// ...// 取消消费,将消息标记为未处理或重新放回消息队列// ... 阅读详情
AI摘要

本文探讨了分布式事务的概念,包括分布式系统、事务、本地事务和分布式事务的定义。深入解析了CAP理论,介绍了分布式事务的一致性解决方案,如两阶段提交协议(2PC)、事务补偿TCC和利用消息队列实现最终一致性。并分析了各种方案的优缺点。

问题描述:

用户支付完成会将支付状态及订单状态保存在订单数据库中,由订单服务去维护订单数据库。由库存服务去维护库存数据库的信息。下图是系统结构图:

如何实现两个分布式服务(订单服务、库存服务)共同完成一件事即订单支付成功自动减库存,这里的关键是如何保证两个分布式服务的事务的一致性。
尝试解决上边的需求,在订单服务中远程调用减库存接口,伪代码如下:

订单支付结果通知方法{

​ 更新支付表中支付状态为“成功”。
​ 远程调用减库存接口减库存。
}

上边的逻辑说明:
1、更新支付表状态为本地数据库操作。
2、远程调用减库存接口为网络远程调用请求。
3、为保存事务上边两步操作由spring控制事务,当遇到Exception异常则回滚本地数据库操作。
问题如下:
1、如果更新支付表失败则抛出异常,不再执行远程调用,此设想没有问题。
2、如果更新支付表成功,网络远程调用超时会拉长本地数据库事务时间,影响数据库性能。
3、如果更新支付表成功,远程调用减库存成功(减库存数据库commit成功),最后更新支付表commit失败,此时出现操作不一致。
上边的问题涉及到分布式事务控制。

什么是分布式事务
什么是分布式系统:

部署在不同结点上的系统通过网络交互来完成协同工作的系统。
比如:充值加积分的业务,用户在充值系统向自己的账户充钱,在积分系统中自己积分相应的增加。充值系统和积分系统是两个不同的系统,一次充值加积分的业务就需要这两个系统协同工作来完成。

什么是事务:

事务是指由一组操作组成的一个工作单元,这个工作单元具有原子性(atomicity)、一致性(consistency)、隔离性(isolation)和持久性(durability)。

  • 原子性:执行单元中的操作要么全部执行成功,要么全部失败。如果有一部分成功一部分失败那么成功的操作要全部回滚到执行前的状态。

  • 一致性:执行一次事务会使用数据从一个正确的状态转换到另一个正确的状态,执行前后数据都是完整的。

  • 隔离性:在该事务执行的过程中,任何数据的改变只存在于该事务之中,对外界没有影响,事务与事务之间是完全的隔离的。只有事务提交后其它事务才可以查询到最新的数据。

  • 持久性:事务完成后对数据的改变会永久性的存储起来,即使发生断电宕机数据依然在。

什么是本地事务:

本地事务就是用关系数据库来控制事务,关系数据库通常都具有ACID特性,传统的单体应用通常会将数据全部存储在一个数据库中,会借助关系数据库来完成事务控制。

什么是分布式事务:

在分布式系统中一次操作由多个系统协同完成,这种一次事务操作涉及多个系统通过网络协同完成的过程称为分布式事务。这里强调的是多个系统通过网络协同完成一个事务的过程,并不强调多个系统访问了不同的数据库,即使多个系统访问的是同一个数据库也是分布式事务,如下图:

另外一种分布式事务的表现是,一个应用程序使用了多个数据源连接了不同的数据库,当一次事务需要操作多个数据源,此时也属于分布式事务,当系统作了数据库拆分后会出现此种情况。

分布式事务有哪些应用场景:

  1. 电商系统中的下单扣库存
    电商系统中,订单系统和库存系统是两个系统,一次下单的操作由两个系统协同完成
    2)金融系统中的银行卡充值
    在金融系统中通过银行卡向平台充值需要通过银行系统和金融系统协同完成。
    3)教育系统中下单选课业务
    在线教育系统中,用户购买课程,下单支付成功后学生选课成功,此事务由订单系统和选课系统协同完成。
    4) SNS系统的消息发送
    在社交系统中发送站内消息同时发送手机短信,一次消息发送由站内消息系统和手机通信系统协同完成。
如何进行分布式事务控制
CAP理论

CAP理论是分布式事务处理的理论基础:分布式系统在设计时只能在一致性(Consistency)、可用性(Availability)、分区容忍性(PartitionTolerance)中满足两种,无法兼顾三种。

  • 一致性(Consistency):服务A、B、C三个结点都存储了用户数据, 三个结点的数据需要保持同一时刻数据一致性。
  • 可用性(Availability):服务A、B、C三个结点,其中一个结点宕机不影响整个集群对外提供服务,如果只有服务A结点,当服务A宕机整个系统将无法提供服务,增加服务B、C是为了保证系统的可用性。
  • 分区容忍性(Partition Tolerance):分区容忍性就是允许系统通过网络协同工作,分区容忍性要解决由于网络分区导致数据的不完整及无法访问等问题。

分布式系统不可避免的出现了多个系统通过网络协同工作的场景,结点之间难免会出现网络中断、网延延迟等现象,这种现象一旦出现就导致数据被分散在不同的结点上,这就是网络分区

分布式系统如果兼顾CAP?

在保证分区容忍性的前提下一致性和可用性无法兼顾,如果要提高系统的可用性就要增加多个结点,如果要保证数据的一致性就要实现每个结点的数据一致,结点越多可用性越好,但是数据一致性越差。所以,在进行分布式系统设计时,同时满足“一致性”、“可用性”和“分区容忍性”三者是几乎不可能的。

CAP有哪些组合方式?
  1. CA:放弃分区容忍性,加强一致性和可用性,关系数据库按照CA进行设计。
  2. AP:放弃一致性,加强可用性和分区容忍性,追求最终一致性,很多NoSQL数据库按照AP进行设计。
    说明:这里放弃一致性是指放弃强一致性,强一致性就是写入成功立刻要查询出最新数据。追求最终一致性是指允许暂时的数据不一致,只要最终在用户接受的时间内数据 一致即可。
  3. CP:放弃可用性,加强一致性和分区容忍性,一些强一致性要求的系统按CP进行设计,比如跨行转账,一次转账请求要等待双方银行系统都完成整个事务才算完成。说明:由于网络问题的存在CP系统可能会出现待等待超时,如果没有处理超时问题则整理系统会出现阻塞。

总结

​ 在分布式系统设计中AP的应用较多,即保证分区容忍性和可用性,牺牲数据的强一致性(写操作后立刻读取到最新数据),保证数据最终一致性。比如:订单退款,今日退款成功,明日账户到账,只要在预定的用户可以接受的时间内退款事务走完即可。

分布式事务一致性解决方案
两阶段提交协议(2PC)

​ 为解决分布式系统的数据一致性问题出现了两阶段提交协议(2 Phase Commitment Protocol),两阶段提交由协调者和参与者组成,共经过两个阶段和三个操作,部分关系数据库如Oracle、MySQL支持两阶段提交协议,本节讲解关系数据库两阶段提交协议。

参考:
2PC:https://en.wikipedia.org/wiki/Two-phase_commit_protocol

2PC协议流程图

1)第一阶段:准备阶段(prepare)
协调者通知参与者准备提交订单,参与者开始投票。
参与者完成准备工作向协调者回应Yes|NO。
2)第二阶段:提交(commit)/回滚(rollback)阶段
协调者根据参与者的投票结果发起最终的提交指令。
如果有参与者没有准备好则发起回滚指令。

一个下单减库存的例子:

(img-gg22D205-1571586550916)(https://i.loli.net/2019/10/20/4l8sradhvi1BuqG.png)]

  1. 应用程序连接两个数据源。
  2. 应用程序通过事务协调器向两个库发起prepare,两个数据库收到消息分别执行本地事务(记录日志),但不提交,如果执行成功则回复yes,否则回复no。
  3. 事务协调器收到回复,只要有一方回复no则分别向参与者发起回滚事务,参与者开始回滚事务。
  4. 事务协调器收到回复,全部回复yes,此时向参与者发起提交事务。如果参与者有一方提交事务失败则由事务协调器发起回滚事务。

2PC的优点:实现强一致性,部分关系数据库支持(Oracle、MySQL等)。
缺点:整个事务的执行需要由协调者在多个节点之间去协调,增加了事务的执行时间,性能低下。
解决方案有:springboot+Atomikos or Bitronix

3PC主要是解决协调者与参与者通信阻塞问题而产生的,它比2PC传递的消息还要多,性能不高。详细参考3PC:
https://en.wikipedia.org/wiki/Three-phase_commit_protocol

事务补偿 TCC

TCC事务补偿是基于2PC实现的业务层事务控制方案,它是Try、Confirm和Cancel三个单词的首字母,含义如下:
1、Try 检查及预留业务资源完成提交事务前的检查,并预留好资源。
2、Confirm确定执行业务操作对try阶段预留的资源正式执行。
3、Cancel取消执行业务操作对try阶段预留的资源释放。

下边用一个下单减库存的业务为例来说明:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WV6xbtry-1571586550917)(https://i.loli.net/2019/10/20/qndSjc5VOaKMAh8.png)]

1、Try

  • 下单业务由订单服务和库存服务协同完成,在try阶段订单服务和库存服务完成检查和预留资源。
  • 订单服务检查当前是否满足提交订单的条件(比如:当前存在未完成订单的不允许提交新订单)。
  • 库存服务检查当前是否有充足的库存,并锁定资源。

2、Confirm

  • 订单服务和库存服务成功完成Try后开始正式执行资源操作。
  • 订单服务向订单写一条订单信息。
  • 库存服务减去库存。

3、Cancel

  • 如果订单服务和库存服务有一方出现失败则全部取消操作。
  • 订单服务需要删除新增的订单信息。
  • 库存服务将减去的库存再还原。

优缺点

  • 优点:最终保证数据的一致性,在业务层实现事务控制,灵活性好。
  • 缺点:开发成本高,每个事务操作每个参与者都需要实现try/confirm/cancel三个接口。

注意:TCC的try/confirm/cancel接口都要实现幂等性,在为在try、confirm、cancel失败后要不断重试。

什么是幂等性?
幂等性是指同一个操作无论请求多少次,其结果都相同。
幂等操作实现方式有:
1、操作之前在业务方法进行判断如果执行过了就不再执行。
2、缓存所有请求和处理的结果,已经处理的请求则直接返回结果。
3、在数据库表中加一个状态字段(未处理,已处理),数据操作时判断未处理时再处理。

消息队列实现最终一致性

本方案是将分布式事务拆分成多个本地事务来完成,并且由消息队列异步协调完成,如下图:
下边以下单减少库存为例来说明:

可以把MQ去掉不使用MQ

1、订单服务和库存服务完成检查和预留资源。
2、订单服务在本地事务中完成添加订单表记录和添加“减少库存任务消息”。
3、由定时任务根据消息表的记录发送给MQ通知库存服务执行减库存操作。
4、库存服务执行减少库存,并且记录执行消息状态(为避免重复执行消息,在执行减库存之前查询是否执行过此消息)。
5、库存服务向MQ发送完成减少库存的消息。
6、订单服务接收到完成库存减少的消息后删除原来添加的“减少库存任务消息”。
实现最终事务一致要求:预留资源成功理论上要求正式执行成功,如果执行失败会进行重试,要求业务执行方法实现幂等。

优点 :
由MQ按异步的方式协调完成事务,性能较高。
不用实现try/confirm/cancel接口,开发成本比TCC低。
缺点:
此方式基于关系数据库本地事务来实现,会出现频繁读写数据库记录,浪费数据库资源,另外对于高并发操作不是最佳方案。

浅谈分布式事务

解决Java分布式事务问题的实践方法 在传统的单机事务中,事务的管理由数据库系统自动完成,而在分布式环境下,由于存在多个参与方,需要通过协调和一致性机制来保证事务的正确执行。通过使用消息队列,可以将事务操作和消息发送操作放在同一个事务中,保证了事务的一致性。当事务操作抛出异常时,会捕获异常并执行相应的补偿操作,以撤销已经执行的操作。该模式基于"回滚"操作,当事务的一部分操作失败时,通过执行补偿操作来撤销已经执行的操作。两阶段提交协议是一种常用的解决分布式事务问题的方法。类从消息队列中接收事务操作消息,并根据消息的内容执行相应的事务操作。 阅读详情

相关推荐

Java分布式事务(二)

事务就是针对数据库的一组操作,它可以由一条或多条SQL语句组成,同一个事务的操作具备同步的特点,事务中的语句要么都执行,要么都不执行。

本人是在学习Java的小白,希望各位大佬多多指教! 773

【分布式】java实现分布式事务的五种方案

部署在不同结点上的系统通过网络交互来完成协同工作的系统。比如:充值加积分的业务,用户在充值系统向自己的账户充钱,在积分系统中自己积分相应的增加。充值系统和积分系统是两个不同的系统,一次充值加积分的业务就需要这两个系统协同工作来完成。事务是指由一组操作组成的一个工作单元,这个工作单元具有原子性(atomicity)、一致性(consistency)、隔离性(isolation)和持久性(durability)。原子性:执行单元中的操作要么全部执行成功,要么全部失败。

DreamSun的博客 8012

Qt实战:用QTreeView+QStandardItemModel实现多级多列文件浏览器(附完整代码)

本文深入探讨了使用Qt的QTreeView与QStandardItemModel构建多级多列文件浏览器的完整实践。通过分析模型/视图框架的优势,详细演示了从基础框架搭建、模拟数据填充,到对接真实文件系统实现懒加载的全过程。文章还涵盖了自定义委托、多列排序、右键菜单等高级定制技巧,并提供了性能优化建议和完整的代码示例,帮助开发者打造功能强大且高效的工业级文件管理界面。

weixin_29021291的博客 423

java分布式事务——9种解决方案的原理与分类

Prepare 阶段:事务管理器给每个资源管理器发送 prepare 消息,资源管理器判断是否可以执行事务。若可以执行,则开启本地事务,将事务写入本地的 redo log 和 undo log,但是不提交,然后返回成功;若不可以执行,则返回失败。Commit 阶段:若事务管理器没有收到任何资源管理器的失败反馈,则给所有资源管理器发送 commit 消息;若事务管理器收到了部分资源管理器的失败反馈,则给所有资源管理器发送 rollback 消息。

xiaoyaozizai1的博客 3144

2025年第十六届蓝桥杯省赛C/C++大学B组 个人题解

也是写了写部分题解,朱波也是狠狠水了个省二┭┮﹏┭┮,毕竟许多算法知识没怎么学。

2301_80173664的博客 2430

python实现语音信号的分帧、加窗、预处理

语音信号实现分帧、加窗、预处理音频文件读取预加重分帧加窗 音频文件读取 librosa是非常强大的python语音信号处理库。 读取音频: 使用语句librosa.load(path, sr=22050, mono=True, offset=0.0, duration=None)读取音频文件,默认的采样率是22050,若要保留音频的原始采样率,使用sr=None。 其中: path:表示音频文件的路径 sr:表示采样率 mono:bool,是布尔类型,表示是否将信号转换为单声道 offset:float,后

weixin_45272908的博客 1万+

CMS-订单系统的分布式事务如何处理

2 分布式事务 2.1 问题描述 用户支付完成会将支付状态及订单状态保存在订单数据库中,由订单服务去维护订单数据库。而学生选课信息在学 习中心数据库,由学习服务去维护学习中心数据库的信息。下图是系统结构图: 如何实现两个分布式服务(订单服务、学习服务)共同完成一件事即订单支付成功自动添加学生选课的需求,这里 的关键是如何保证两个分布式服务的事务的一致性。 尝试解决上边的需求,在订单服务中远程调用...

逍遥云恋 3049

一体化伺服电机与施耐德PLC TM241CEC24T在Canopen协议下的应用

一.硬件组成 软件组成:施耐德SoMachineV4.3二.○1.打开SoMachineV4.3,点击“新建项目”○2.点击“空白项目”○3.项目命名○4.点击“创建项目” 三. 点击“Logic Builder” 四. ○1.右击项目”PMM_CANOPEN_ST”添加设备○2.点击”LogicController”选择PLC型号TM241CEC24T/U○3.点击“添加设备” 五. ○1.右击CAN_1,添加设备○2.选择“CANopen Perfomance”○3.点击“添加设备”

m0_46512607的博客 2520

java实现事物的两种方式,Java 实现分布式事务的三种方案

问题描述:用户支付完成会将支付状态及订单状态保存在订单数据库中,由订单服务去维护订单数据库。由库存服务去维护库存数据库的信息。下图是系统结构图:image.png如何实现两个分布式服务(订单服务、库存服务)共同完成一件事即订单支付成功自动减库存,这里的关键是如何保证两个分布式服务的事务的一致性。尝试解决上边的需求,在订单服务中远程调用减库存接口,伪代码如下:订单支付结果通知方法{更新支付表中支付状...

weixin_39785600的博客 521

关系代数表达式优化步骤

关系代数表达式优化步骤 本篇主要讲解怎么画查询语法树并对其优化,因为我在学关系代数的语法树的时候,在网上找不到比较详细的教法或者技巧,最后通过答案反推原理,所以想写一篇技巧来描述一下这类题的解题方法。 先上书内讲解 1、构造查询树 第一步:把用高级语言定义的查询转换为关系代数表达式 ★ 以 SELECT子向对应投影操作,以FROM字向对应笛卡尔积以 WHERE子句对应选择操作,生成原始查询树 ★ SQL语句转化为原始查询树 第二步:把关系代数表达式转换为查询树。 注: 查询树是一种表示关系代数表达式的树形结

m0_51718449的博客 7015

猿创征文|SfM(Structure from Motion)学习之路

SfM全称Structure from Motion,译为运动恢复结构,是三维重建pipeline的一部分,又称稀疏重建,在摄影测量领域则称为空三(空中三角测量)。SfM的任务是,给定一系列具有一定重叠度的图像,去同时估计出拍摄每张图像时相机的的位姿(位置t和姿态R)和被拍摄物体或场景的稀疏点云。...............

zeeq的博客 1万+

java实现分布式事务的三种方案,java软件架构设计

尝试解决上边的需求,在订单服务中远程调用减库存接口,伪代码如下: 订单支付结果通知方法{ ​ 更新支付表中支付状态为“成功”。 ​ 远程调用减库存接口减库存。 } 上边的逻辑说明: 1、更新支付表状态为本地数据库操作。 2、远程调用减库存接口为网络远程调用请求。 3、为保存事务上边两步操作由spring控制事务,当遇到Exception异常则回滚本地数据库操作。 问题如下: 1、如果更新支付表失败则抛出异常,不再执行远程调用,此设想没有问题。 2、如果更新支付表成功,网络远程调用超时会拉长

m0_64867152的博客 221

使用Simulink对氢燃料电池与锂电池的混合储能系统进行建模

本文介绍了基于Simulink的氢燃料电池与锂电池混合储能系统建模与协同控制方法。系统通过氢燃料电池提供稳定能源,锂电池实现快速响应,结合DC-DC变换器和负载管理器实现动态调控。详细阐述了从模型创建、关键模块配置到控制器设计的完整流程,重点说明了功率分配算法和充放电控制策略的实现。通过仿真分析验证了系统在不同负载条件下的性能表现,包括响应速度、工作效率和稳定性等指标。该方案为新能源混合储能系统的设计与优化提供了实用指导,有助于提升系统可靠性和延长电池寿命。

amy_mhd的博客 314

java后端学习流程图_java实现分布式事务的三种方案

问题描述:用户支付完成会将支付状态及订单状态保存在订单数据库中,由订单服务去维护订单数据库。由库存服务去维护库存数据库的信息。下图是系统结构图:如何实现两个分布式服务(订单服务、库存服务)共同完成一件事即订单支付成功自动减库存,这里的关键是如何保证两个分布式服务的事务的一致性。尝试解决上边的需求,在订单服务中远程调用减库存接口,伪代码如下:订单支付结果通知方法{​ 更新支付表中支付状态为“成功”。...

weixin_42527464的博客 443

YOLO26涨点改进 | NeurIPS2025最佳论文!注意力改进篇| 引入Gated Attention门控注意力模块、太牛了!直接拯救了大模型的发展,助力目标检测、图像分割、图像分类有效涨点

本文提出了一种基于门控注意力机制(GatedAttention)的YOLO26模型改进方法。该方法在标准softmax注意力机制中引入头部特定的sigmoid门控,通过增强注意力机制使模型更聚焦于关键信息。实验表明,该模块能显著提升模型性能,特别是在复杂背景和密集目标场景中,同时减少无关区域关注并提高检测精度。门控机制引入的非线性和稀疏性不仅提升了推理效率,还改善了训练稳定性,使模型能采用更大学习率并增强扩展性。此外,该方法有效缓解了"注意力下沉"现象,增强了模型对长距离目标的感知能力。

Ai缝合怪、助力小伙伴高效发论文 650

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

j2ee中spring的分布式事务实现及解决方案

1 java事务类型 Java事务的类型有三种:JDBC事务、JTA(Java Transaction API)事务、容器事务。 常见的容器事务如Spring事务,容器事务主要是J2EE应用服务器提供的,容器事务大多是基于JTA完成,这是一个基于JNDI的,相当复杂的API实现。本人非常厌恶使用JNDI来访问容器组件,所以不推荐使用容器事务。不知道JNDI是什么的,可以访问jndi通俗...

dichengyan0013的博客 218

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

上一篇: mybatis——mapper文件详解
下一篇: springboot配置文件读取pom文件信息
刘彦青-Yannis
博客等级 码龄10年 1万+粉丝 234原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刘彦青-Yannis

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值