分布式事务处理方案
1. 使用Seata框架解决
1.1 XA 事务
1.1.1 XA整体流程
- 第一阶段
- RM1开启XA事务-> 执行业务SQL -> 上报TC执行结果
- RM2开启XA事务-> 执行业务SQL -> 上报TC执行结果
- 第二阶段
- TC根据 RM上报结果通知RM一起提交/回滚XA事务
1.1.2 XA特点
- XA 模式必须要有数据库的支持,它开启的是XA事务,不是我们普通的本地事务。
-- 数据库1XA START 'xid1';UPDATE table1 SET col1=1 WHERE id=1;XA END 'xid1';XA PREPARE 'xid1';-- 数据库2XA START 'xid1';INSERT INTO table2 VALUES (2);XA END 'xid1';XA PREPARE 'xid1';-- 提交所有分支事务XA COMMIT 'xid1';
- XA模式是各分支事务执行完成业务SQL后会使用数据库锁一直锁定资源,直到收到事务协调者的消息后统一进行提交或回滚XA事务,所以是强一致性,并且全程锁定资源,性能很低。
1.2 AT模式
1.2.1 整体流程
-
第一阶段
-
RM1:开启本地事务 -> 业务SQL + undo_log -> 获取记录全局锁 -> 提交本地事务 -> 上报给TC执行结果
-
RM2:开启本地事务 -> 业务SQL + undo_log -> 获取记录全局锁 -> 提交本地事务 -> 上报给TC执行结果
-
-
第二阶段
- TC根据各分支执行结果选择事务提交或回滚
- 提交:提交全局事务,释放全局锁,异步删除undo_log日志
- 回滚:根据undo_log日志异步反向执行SQL进行反向补偿回滚操作,并删除undo_log记录。
- TC根据各分支执行结果选择事务提交或回滚
1.2.2 AT模式特点
- 在数据库本地事务隔离级别 读已提交(Read Committed) 或以上的基础上,Seata(AT 模式)的默认全局隔离级别是 读未提交(Read Uncommitted) 。
- 一阶段本地事务提交前,需要确保先拿到 全局锁 。拿不到 全局锁 ,不能提交本地事务。拿 全局锁 的尝试被限制在一定范围内,超出范围将放弃,并回滚本地事务,释放本地锁。
- 一阶段提交后会立即释放本地锁和连接资源,性能高。
1.3 TCC模式
1.3.1 TCC模式整体流程
- 一阶段:(Try):
- RM1:开启本地事务 -> 资源预留锁定SQL -> 提交本地事务。上报状态给TC。
- RM2:开启本地事务 -> 资源预留锁定SQL -> 提交本地事务。上报状态给TC。
- 二阶段:(Confirm/Cancel)::
- RM1:执行业务操作。上报事务状态给TC。
- RM2:回滚取消资源预留操作。上报事务状态给TC。
TCC 的Confirm /Cancel 操作在业务逻辑上是不允许返回失败的,如果因网络或其他故障失败会不断重试,直到成功,所以要求Confirm /Cancel 必须幂等。一般用在对中间状态有约束的业务中。try阶段设置中间状态锁定资源,确认阶段更新业务并设置为最终态,回滚阶段设置中间态为原始状态,其相关并发业务要考虑中间态的数据。
1.3.2 TCC模式特点
- 需要硬编码实现Try,Confirm,Cancel 三个操作,对业务系统有着非常大的入侵性。
- Try,Confirm,Cancel 三个操作都是独立的本地事务,不会长时间锁定资源,性能高。
1.3.3 TCC异常问题
- 空回滚:Try未执行,Cancel执行。原因:一个分支事务网络异常导致Try阶段未执行成功,故障恢复后,分布式事务进行回滚则会调用二阶段的Cancel方法,从而形成空回滚。
- 幂等:多次执行cancel() 或者 confirm()。原因:在重试过程中,实际重试成功了,但是由于网络原因,协调者没接收到重试成功的消息,再次去执行重试。
- 悬挂:Cancel在Try之前执行。原因:在 RPC 调用分支事务try时,此时网络发生拥堵,超过一定时间后协调者认为其执行出错了,通知其回滚该分布式事务,可能回滚完成后。Try 的 RPC 请求才到达参与者真正执行。
- 解决方案:设计一张事务状态记录表,在执行Try、confirm、Cancel 前对事务状态进行判断。seata已经帮助我们实现了。
1.4 SAGA模式
1.4.1 整体流程
Saga模式是SEATA提供的长事务解决方案,在Saga模式中,业务流程中每个参与者都提交本地事务,当出现某一个参与者失败则补偿前面已经成功的参与者,一阶段正向服务和二阶段补偿服务都由业务开发实现。
1.4.2 SAGA模式特点
- 一阶段提交本地事务,无锁,高性能
- 事件驱动架构,参与者可异步执行,高吞吐
- 补偿服务易于实现
- 不保证隔离性
1.5 Seata 各事务模式比较
XA | AT | TCC | SAGA | |
---|---|---|---|---|
一致性 | 强一致 | 弱一致 | 弱一致 | 最终一致性 |
隔离性 | 完全隔离 | 基于全局锁隔离 | 基于资源预留隔离 | 无隔离 |
代码侵入 | 无 | 无 | 有,编写三个接口 | 有,编写状态机和补偿业务 |
性能 | 差 | 好 | 非常好 | 非常好 |
场景 | 1.对一致性、隔离性有高要求的业务。2.需数据库支持XA协议。 | 1.基于关系型数据库的大多场景都可以。 | 对性能要求高的事务 | 1.业务流程长。2.参与者包含遗留系统,无法提供TCC三个接口 |
2. 使用消息队列解决
- 使用消息队列去解决分布式事务的特点就是事务参与者之间互相解耦,来实现事务的最终一致性。
- 使用消息队列就需要解决消息的可靠投递和消费。
- 由于事务参与者之间互相解耦,都以本地事务提交,所以没有隔离性。
2.1 使用RocketMQ事务消息实现
- 消息预投递:生产这者发送半事务消息到Broker,这个消息不会被立即消费,处于一个预提交状态。
- 本地事务执行:执行本地业务,提交本地数据库事务。
- 消息确认:提交/回滚消息,Broker将消息标记为已投递状态,消息可被正常消费。或者Broker回滚这个半事务消息,消息会被删除。
- 消息消费:其他事务参与者进行消息消费。
- 消费成功:一切OK
- 消费失败:重新消费,达到次数阈值后可选择人工参与,或者反向投递事务消息对上游业务进行回滚。
如果Broker未收到第二阶段消息确认,会回查消息事务状态来确定消息状态,这里需要实现 RocketMQ 的
TransactionListener
接口,提供一个回查的接口。
2.2 使用其他MQ进行实现
其他MQ没有事务消息的特性,需实现借助本地消息表实现消息不丢失的问题。大致流程如下:
- 本地事务执行:执行本地业务SQL + 消息表SQL,提交本地数据库事务。
- 投递消息:异步扫描本地消息表获取未投递MQ的记录进行MQ投递。
- 消息消费:其他事务参与者进行消息消费。更新消息表记录状态。
由于为保证消息的可靠性引入本地消息表,并且定时异步扫描,所以在性能方面要比RocketMQ差,并且代码量会更大,设计更加复杂。
相关文章:

分布式事务处理方案
1. 使用Seata框架解决 1.1 XA 事务 1.1.1 XA整体流程 第一阶段 RM1开启XA事务-> 执行业务SQL -> 上报TC执行结果RM2开启XA事务-> 执行业务SQL -> 上报TC执行结果 第二阶段 TC根据 RM上报结果通知RM一起提交/回滚XA事务 1.1.2 XA特点 XA 模式必须要有数据库的支…...

CVE-2024-36467 Zabbix权限提升
漏洞描述 在Zabbix中,具有API访问权限的已认证用户(例如具有默认用户角色的用户)可以通过调用user.update API接口,将自己添加到任何用户组(如Zabbix管理员组)。然而,用户无法添加到已被禁用或…...

Dify中的自定义模型插件开发例子:以xinference为例
本文使用Dify v1.0.0-beta.1版本。模型插件结构基本是模型供应商(模型公司,比如siliconflow、xinference)- 模型分类(模型类型,比如llm、rerank、speech2text、text_embedding、tts)- 具体模型(…...
crud方法命名示例
以下是基于表名dste_project_indicator(项目指标表)的完整命名示例,覆盖各类增删改查场景: 1. 表名与实体类映射 // 表名:dste_project_indicator // 实体类:DsteProjectIndicatorEntity public class Ds…...

尚硅谷redis7 33-36 redis持久化之RDB优缺点及数据丢失案例
官网说明优点: RDB是Redis数据的一个非常紧凑的单文件时间点表示,RDB文件非常适合备份。例如,您可能希望在最近的24小时内每小时旧档一次RDB文件,并在30天内每天保存一个RDB快照,这使您可以在发生来难时轻松恢复不同版本的数据集。RDB非常适合灾难恢复,它是一个可以…...
No such file or directory: ‘ffprobe‘
目录 详细信息: 解决方法: No such file or directory: ffprobe 详细信息: File "/usr/local/lib/python3.10/dist-packages/framepump/framepump.py", line 168, in get_duration return float(ffmpeg.probe(video_path)[form…...

计算机网络-WebSocket/DNS/Cookie/Session/Token/Jwt/Nginx
文章目录 WebSocketDNS什么是dns域名解析底层协议 cookie/sessionToken/JWTNginx WebSocket 一种网络通信协议,允许在单个 TCP(半双工) 连接上进行全双工通信(客户端和服务器可同时双向传输数据)。 HTTP是基于请求-响…...
功能“递归模式”在 C# 7.3 中不可用,请使用 8.0 或更高的语言版本的一种兼容处理方案
原程序: internal class ControllerParameterCreator : IParameterCreator {private Controller controller;public ControllerParameterCreator(Controller controller){this.controller controller;}public Parameter CreateSystem(string name, int unused){re…...
第4章-操作系统知识
存储管理 固定分区:一种静态分区方式请求分页存储管理覆盖技术:覆盖技术是指让作业中不同时运行的程序模块共同使用同一主存区域。...

将网页带格式转化为PDF
# 一、安装插件 SingleFile | 将完整的页面保存到一个 HTML 文件中 – 下载 🦊 Firefox 扩展(zh-CN) 打开火狐浏览器,安装上面的插件 # 二、下载html单文件 打开对应的网页,点击插件下载对应的html文件 # 三、打开…...

【ArcGIS】ArcGIS AI 助手----复现
github地址 korporalK/Archer-GIS-AI-Assitant:Archer 在 ArcGIS Pro 中将自然语言命令转换为自动化 GIS 工作流。它使用代理框架(计划-验证-执行)构建并由 LLM 提供支持,可简化空间分析、减少手动工作并使 GIS 更易于访问。Arch…...
使用 FFmpeg 将视频转换为高质量 GIF(保留原始尺寸和帧率)
在制作教程动图、产品展示、前端 UI 演示等场景中,我们经常需要将视频转换为体积合适且清晰的 GIF 动图。本文将详细介绍如何使用 FFmpeg 工具将视频转为高质量 GIF,包括: ✅ 保留原视频尺寸或自定义缩放✅ 保留原始帧率或自定义帧率✅ 使用调色板优化色彩质量✅ 降低体积同…...
《Java vs Go vs C++ vs C:四门编程语言的深度对比》
引言 从底层硬件操作到云端分布式系统,Java、Go、C 和 C 四门语言各自占据不同生态位。本文从设计哲学、语法范式、性能特性、应用场景等维度进行对比,为开发者提供技术选型参考。 一、设计哲学与历史定位…...

充电枪IEC62196/EN 62196测试内容
充电枪IEC62196/EN 62196测试内容 一、机械性能测试 插拔力测试 交流充电接口的插入/拔出力需≤100N,直流接口≤140N。若使用助力装置,操作力仍需满足上述要求。 测试方法:通过弹簧秤或专用试验机(如Sun-CB设备)测…...
有效的字母异位符--LeetCode
题目 给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的 字母异位词。 示例 1: 输入: s "anagram", t "nagaram" 输出: true示例 2: 输入: s "rat", t "car" 输出: false 思路一:排序 t 是 s …...

SAP ERP 系统拆分的七大挑战
在企业变革或管理运营风险时,剥离IT系统能带来显著效益,但SAP ERP系统的复杂性使得这项工作充满挑战。如果管理不当,可能会导致数据不一致、运营中断、合规风险和意外成本。由于SAP ERP系统深度集成于企业核心业务流程中,其拆分工…...

AcrelEMS 3.0智慧能源管理平台:构建企业微电网数智化中枢
安科瑞电气顾强 在"双碳"目标驱动下,企业能源管理正从粗放式运营向精细化、智能化转型。AcrelEMS 3.0智慧能源管理平台以微电网为核心载体,通过"感知-分析-决策-控制"的全链路数字化能力,助力工商企业、医疗机构、教育机…...
【HTML-12】HTML表格常用属性详解:从基础到高级应用
表格是HTML中最强大且常用的元素之一,它能够以结构化的方式展示数据。本文将全面介绍HTML表格的常用属性,帮助您创建美观、响应式且语义化的数据表格。 1. HTML表格基础结构 在深入了解属性之前,我们先回顾一下HTML表格的基本结构ÿ…...

Word转PDF--自动生成目录
1-Word文档中已经包含自动生成的目录; 2-选择“文件”; 3-另存为,PDF; 4-选择“选项”按钮,在弹出的窗口中,勾选“创建书签时使用标题”。...
MySQL组合索引优化策略
优化MySQL组合索引需要综合考虑查询模式、索引结构及数据库特性。以下是关键优化策略及示例: 1. 遵循最左前缀原则 策略:确保查询条件包含组合索引最左侧列。示例:索引(a,b,c)生效场景:WHERE a1 AND b2 -- ✔️ 使用a和b W…...
Spring MVC 的的核心原理与实践指南
一、Spring MVC 概述 Spring MVC 是 Spring 框架中的一个重要模块,用于构建基于 Java 的 Web 应用程序。它遵循模型-视图-控制器(MVC)设计模式,提供了一种结构化的方式来开发灵活、松耦合的 Web 应用。 Spring MVC 的特点…...

轻量级视觉语言模型 Dolphin:高效精准的文档结构化解析利器
在数字化办公和学术研究日益普及的今天,如何高效、准确地处理各类文档图像成为了一个亟需解决的问题。Dolphin 应运而生,作为一款基于异构锚点提示的多模态文档图像解析模型,它不仅打破了传统手动整理文档的繁琐流程,更以远超主流…...

如何安全配置数据库(MySQL/PostgreSQL/MongoDB)
数据库是许多应用程序的核心组成部分,因此保护数据库的安全性至关重要。无论是MySQL、PostgreSQL还是MongoDB,都需要经过适当的安全配置才能防止潜在的安全威胁。本文将介绍如何安全配置这些流行的数据库管理系统,以确保数据的保密性、完整性…...

将 Docker 镜像从服务器A迁移到服务器B的方法
在日常工作中,我们有时会需要将服务器 A上的镜像上传至服务器B上,下面给出具体操作方式,以镜像 postgres:15 为例进行讲解。 首先在服务器A上拉取 镜像 postgres:15 ,命令如下: docker pull postgres:15下面再将服务…...
git merge解冲突后,add、continue提交
git merge解冲突后,add、continue提交 git merge操作冲突后,需要手动解冲突,解完冲突后,需要: git add . 然后,进入一般的正常git代码提交流程。 git合并‘merge’其他分支的个别文件到当前branch_gitbash 合并branc…...
Lines of Thought in Large Language Models
Lines of Thought in Large Language Models 《Lines of Thought in Large Language Models》(大语言模型中的思维链)聚焦于分析大语言模型(LLMs)在生成文本时,其内部向量轨迹的统计特性。 核心目标是揭示LLMs复杂的“思维过程”(即文本生成时的隐藏状态变化)能否被简…...
八股战神-JVM知识速查
1.JVM组成 JVM由那些部分组成,运行流程是什么? JVM是Java程序的运行环境 组成部分: 类加载器:加载字节码文件到内存 运行时数据区:包括方法区,堆,栈,程序计数器,本地…...
机试 | STL | string | 文字处理软件
题目: P5734 【深基6.例6】文字处理软件 - 洛谷 不使用库函数 #include<stdio.h> #include <iostream> #include<string> using namespace std;int main() {int q;//第一行输入一个正整数q,表示操作次数string content;//第二行输入一…...

运动规划实战案例 | 图解基于状态晶格(State Lattice)的路径规划(附ROS C++/Python仿真)
目录 1 控制采样 vs 状态采样2 State Lattice路径规划2.1 算法流程2.2 Lattice运动基元生成2.3 几何代价函数2.4 运动学约束启发式 3 算法仿真3.1 ROS C仿真3.2 Python仿真 1 控制采样 vs 状态采样 控制采样的技术路线源自经典的运动学建模思想。这种方法将机器人的控制指令空…...
深入浅出对抗学习:概念、攻击、防御与代码实践
深入浅出对抗学习:概念、攻击、防御与代码实践 近年来,深度学习在图像识别、自然语言处理等领域取得了巨大成功。然而,研究表明,这些看似强大的模型却异常脆弱,容易受到**对抗样本(Adversarial Examples&a…...