当前位置: 首页 > article >正文

DDD - 可能会用到的分布式事务

一、分布式事务的概念:

分布式事务是指跨越多个独立的资源或服务(例如多个数据库、微服务、消息队列等)执行的事务操作,其目标是确保整个事务在多个系统中保持原子性和一致性,即要么所有操作全部成功提交,要么全部回滚,从而避免部分操作成功导致数据不一致。

关键概念

  1. 原子性、一致性、隔离性、持久性(ACID)
    在单个数据库中的事务通常满足ACID原则,分布式事务则需要在多个系统中同时保证这些特性。

  2. 分布式环境的挑战

    • 不同系统可能位于不同网络节点,存在通信延迟、网络故障等问题。
    • 各系统之间没有共享内存,协调各节点的操作需要额外的协议和机制。
  3. 协调协议
    为了实现跨多个节点的事务一致性,常用的协调协议有:

    • 两阶段提交协议(2PC)
      第一阶段是准备阶段(Prepare Phase),协调者向所有参与者发送准备提交请求;第二阶段是提交阶段(Commit Phase),如果所有参与者都确认可以提交,则协调者通知大家提交,否则通知回滚。
    • 三阶段提交协议(3PC)
      在2PC基础上引入一个预提交阶段,进一步降低因协调者故障导致的不确定状态,从而提高系统的容错性。

直观例子

假设一个电商系统中,用户下单涉及三个独立的服务:

  • 订单服务:记录订单信息
  • 库存服务:扣减商品库存
  • 支付服务:处理用户支付

在分布式事务中,为了确保订单、库存和支付三项操作要么全部成功,要么全部失败,需要:

  • 通过2PC协议,由一个协调者负责协调这三个服务。
  • 在第一阶段,各个服务进行本地事务的准备工作,预留资源但不提交。
  • 如果所有服务都返回成功,协调者在第二阶段通知所有服务提交操作;如果有一个服务准备失败,协调者通知所有服务回滚。

这样,无论哪个服务出现问题,整个下单操作都会保证数据一致性,不会出现只有部分服务更新成功的情况。

分布式事务的核心在于如何在多个独立系统间协调操作,确保整个事务操作的原子性和一致性。通过像两阶段提交这样的方法,可以在分布式环境下尽可能保证ACID特性,但同时也会带来性能和复杂度上的挑战。理解分布式事务有助于设计健壮的分布式系统,并在需要严格数据一致性的场景下正确处理跨服务的数据更新。

二、如何实现分布式事务:

分布式事务的实现通常需要协调多个独立系统或服务中的本地事务,使它们共同满足ACID(原子性、一致性、隔离性、持久性)的要求。最常见的实现方式是两阶段提交协议(2PC)。下面通过一个简单的例子说明如何实现分布式事务。

例子:电商订单处理

假设在一个电商系统中,下单操作涉及三个独立的服务,每个服务都有自己的数据库:

  1. 订单服务:负责记录订单信息。
  2. 库存服务:负责扣减相应商品的库存。
  3. 支付服务:负责处理用户支付。

为了保证整个下单操作要么全部成功(订单创建、库存扣减、支付完成),要么全部失败(任何一步失败都需要回滚),我们可以采用两阶段提交协议来实现分布式事务。

两阶段提交协议(2PC)流程

阶段一:准备阶段(Prepare Phase)
  • 协调者(Transaction Coordinator):由一个专门的协调者负责整个事务的管理。
  • 步骤
    1. 协调者向所有参与服务发送“准备提交”(Prepare)的请求。
    2. 各服务收到请求后,在本地开始事务,并执行各自的业务逻辑,但不提交结果。
    3. 每个服务检查是否可以提交本地事务。如果可以,则返回一个“准备就绪”(Ready)的响应;如果遇到问题,则返回“拒绝”(Abort)的响应。
阶段二:提交阶段(Commit Phase)
  • 决策
    • 如果所有参与者都返回“准备就绪”,协调者则向所有参与者发送“提交事务”(Commit)的命令,各参与者正式提交本地事务。
    • 如果有任何一个参与者返回拒绝,协调者则向所有参与者发送“回滚事务”(Rollback)的命令,各参与者撤销之前的操作。

示例过程

  1. 下单请求发起
    用户下单,订单服务、库存服务和支付服务各自启动一个本地事务,并接到协调者的准备请求。

  2. 准备阶段

    • 订单服务检查订单数据是否完整,并预先锁定相关记录,返回“准备就绪”。
    • 库存服务检查库存是否充足,并预留库存,返回“准备就绪”。
    • 支付服务检查支付信息,预授权用户账户,返回“准备就绪”。
  3. 协调者决策
    协调者收到所有服务的“准备就绪”响应后,判断整个事务可以提交。

  4. 提交阶段
    协调者向所有参与服务发送“提交”命令。

    • 订单服务提交订单记录。
    • 库存服务正式扣减库存。
    • 支付服务完成支付处理。

如果在准备阶段中,任何一个服务返回“拒绝”(比如库存不足或支付失败),协调者会通知所有服务回滚事务,从而保证整个下单操作不会部分成功。

总结

  • **两阶段提交(2PC)**是实现分布式事务的常用机制,主要分为准备阶段和提交阶段。
  • 通过协调者统一管理各参与者的本地事务,2PC确保了跨服务操作的原子性,即要么所有服务的事务都提交,要么全部回滚,保持数据一致性。
  • 这个例子展示了电商系统中订单、库存和支付服务如何协同工作,确保整个下单操作的完整性。

这种实现方式虽然能保证数据一致性,但也存在性能开销和单点故障问题,因此在大规模分布式系统中,有时会采用其他机制(如三阶段提交、最终一致性方案、Saga模式等)来权衡一致性和性能。

三、上面提到的协调者是由什么来做?

协调者在分布式事务中起到“指挥官”的作用,负责协调所有参与者(各个服务或数据库)共同完成或回滚事务。关于协调者的具体实现方式,有以下几点说明:

  1. 协调者的角色

    • 协调者负责在分布式事务中发出“准备”、“提交”或“回滚”的指令。
    • 它收集所有参与者在准备阶段的响应,根据这些响应决定整个事务是提交还是回滚。
  2. 实现方式

    • 协调者可以由专门的分布式事务管理器或中间件实现。例如,一些数据库集群或企业级事务处理系统会内置这样的协调机制。
    • 在微服务架构中,协调者通常作为一个独立的服务或者一个组件存在,专门负责管理分布式事务。
    • 现代分布式系统也可能采用更灵活的模式(如 Saga 模式),在这种情况下,协调逻辑可能嵌入到各个服务的业务流程中,而不依赖单一的协调者。
  3. 实例说明
    例如,在采用两阶段提交(2PC)的分布式事务中,协调者可以是一个专门的事务管理服务,它:

    • 发送准备请求到所有参与者;
    • 收集各参与者的反馈(准备就绪或拒绝);
    • 根据反馈决定是否发送提交或回滚指令;
    • 确保所有参与者最终达成一致,保持数据一致性。

四、分布式事务为什么会存在性能开销和单点故障问题?

在分布式事务中,多个服务或数据库需要协调一致地执行一个整体操作,这就不可避免地引入了额外的复杂性和开销,具体原因如下:

  1. 性能开销

    • 通信延迟:分布式事务要求多个节点之间进行消息传递,如在两阶段提交协议中,协调者需要向所有参与者发送“准备”请求,并等待它们的响应。网络通信的延迟会显著影响整体事务的完成时间。
    • 资源锁定:为了保证一致性,各个参与者在事务执行过程中可能需要对数据加锁,防止其他事务同时修改这些数据。锁定资源会导致其他操作等待,从而降低系统吞吐量。
    • 额外的协调与日志记录:分布式事务管理器需要记录每个节点的状态和操作日志,以便在发生错误时进行回滚。这些额外的操作本身也会带来计算和 I/O 的开销。
  2. 单点故障问题

    • 协调者风险:在传统的两阶段提交中,协调者(Transaction Coordinator)负责整体的事务协调。如果协调者节点出现故障,整个事务可能陷入不确定状态,因为其他参与者可能处于锁定状态,无法决定提交或回滚。
    • 依赖集中化:如果协调者没有冗余或备份机制,整个分布式事务系统就会依赖于这个单一的节点,导致其成为整个系统的瓶颈和单点故障(SPOF)。

分布式事务需要在多个独立节点之间保证数据一致性,这要求进行频繁的通信、协调和资源锁定,从而导致性能开销;同时,由于依赖于一个协调者进行全局管理,协调者一旦失效,就可能影响整个系统的正常运行,形成单点故障问题。为了应对这些问题,实际系统中常常采用改进的协议(如三阶段提交、Saga模式)以及冗余设计来降低风险。

附加Saga模式:

Saga 模式是一种处理分布式事务的方法,它通过将一个长事务拆分为一系列相互独立的本地事务来实现。每个本地事务完成后,会产生一个“补偿事务”(Compensating Transaction),用于在后续步骤出现问题时撤销前面的操作。这样,不需要像传统的两阶段提交(2PC)那样锁定资源,也不会因为单一协调者故障而导致整个事务挂起。

主要特点

  1. 事务拆分
    一个全局事务被拆分成多个独立的本地事务,每个本地事务在各自服务中独立执行,并在成功后提交。

  2. 补偿机制
    如果在执行后续本地事务过程中发生失败,系统会依次执行对应的补偿事务,撤销之前已经成功提交的操作,从而达到最终一致性(Eventual Consistency)。

  3. 异步与解耦
    Saga 模式通常通过异步消息传递实现各个事务之间的协调,降低了系统耦合度和网络延迟对事务的影响。

举例说明

假设一个电商系统中,下单操作涉及三个服务:

  • 订单服务:记录订单信息
  • 库存服务:扣减库存
  • 支付服务:完成支付

使用 Saga 模式的流程如下:

  1. 步骤1:订单服务创建订单,成功后提交本地事务,并发布“订单已创建”事件。
  2. 步骤2:库存服务接收到该事件,执行扣减库存的本地事务,并提交。如果库存不足导致失败,则需要执行补偿事务,比如取消订单服务中已创建的订单(撤销操作)。
  3. 步骤3:支付服务接收到订单和库存操作都成功的消息后,执行支付本地事务。如果支付失败,则需要先执行支付补偿(如退款),再执行库存补偿(恢复库存),最后再执行订单补偿(取消订单)。

通过这种方式,每个服务都独立执行本地事务,而补偿事务则用于“回滚”那些已经成功执行但后来发现整体事务无法完成的操作,从而保证系统最终达到一致性。

Saga 模式通过将全局事务拆分为多个独立的本地事务,并为每个本地事务设计补偿逻辑,避免了分布式锁和两阶段提交带来的性能和单点故障问题。它适用于需要长时间运行且无法保证即时一致性的分布式系统,例如电商、银行、预订系统等场景。

相关文章:

DDD - 可能会用到的分布式事务

一、分布式事务的概念: 分布式事务是指跨越多个独立的资源或服务(例如多个数据库、微服务、消息队列等)执行的事务操作,其目标是确保整个事务在多个系统中保持原子性和一致性,即要么所有操作全部成功提交,…...

DeepSeek + Vue实战开发

利用DeepSeek V3模型、siliconflow大模型一站式云服务平台以及vue3.0实现一个在线人工智能客服对话系统。 因为deepseek官网的api密钥使用起来比较缓慢,所以可以使用第三方的,具体操作请自行查阅资料。 siliconflow官网 SiliconFlow, Accelerate AGI …...

【数据结构】(8) 二叉树

一、树形结构 1、什么是树形结构 根节点没有前驱,其它节点只有一个前驱(双亲/父结点)。所有节点可以有 0 ~ 多个后继,即分支(孩子结点)。每个结点作为子树的根节点,这些子树互不相交。 2、关于…...

拉链表介绍

拉链表(Slowly Changing Dimension, Type 2) 是一种在数据仓库中用于跟踪维度数据历史变化的存储技术。它通过记录数据的生命周期(开始时间和结束时间)来保留历史状态,同时避免全量存储冗余数据。以下是详细解释及实际…...

Web 后端 请求与响应

一 请求响应 1. 请求(Request) 客户端向服务器发送的HTTP请求,通常包含以下内容: 请求行:HTTP方法(GET/POST等)、请求的URL、协议版本。 请求头(Headers):…...

CEF132 编译指南 Linux 篇 - CEF 编译实战:构建 CEF(六)

1. 引言 经过前几篇的精心准备,我们已经完成了所有必要的环境配置和源码下载。现在,我们将进入激动人心的 CEF 编译阶段。本篇将详细指导你在 Linux 系统上编译 CEF 6834 分支(对应 Chromium 132 版本),包括创建项目文…...

奥比中光3D机器视觉相机能连接halcon吗?

奥比中光的设备与Halcon的兼容性可以通过以下方式实现: 数据接口的通用性 奥比中光的相机(如Astro Pro、大白等)支持通过UVC协议获取彩色图像,深度数据则通过OpenNI或ROS2接口传输105。若Halcon支持这些协议或标准接口(如ROS消息、OpenCV图像流),则可通过直接调用或二次…...

【Spring+MyBatis】_图书管理系统(上篇)

目录 1. MyBatis与MySQL配置 1.1 创建数据库及数据表 1.2 配置MyBatis与数据库 1.2.1 增加MyBatis与MySQL相关依赖 1.2.2 配置application.yml文件 1.3 增加数据表对应实体类 2. 功能1:用户登录 2.1 约定前后端交互接口 2.2 后端接口 2.3 前端页面 2.4 单…...

【苍穹外卖】学习

软件开发整体介绍 作为一名软件开发工程师,我们需要了解在软件开发过程中的开发流程, 以及软件开发过程中涉及到的岗位角色,角色的分工、职责, 并了解软件开发中涉及到的三种软件环境。那么这一小节,我们将从 软件开发流程、角色…...

DeepSeek-V2-技术文档

DeekSeek-v2-简述 1. DeepSeek-V2是什么? DeepSeek-V2是一个基于混合专家(Mixture-of-Experts,简称MoE)架构的语言模型。它是一种新型的人工智能模型,专门用于处理自然语言处理(NLP)任务,比如文本生成、翻译、问答等。与传统的语言模型相比,DeepSeek-V2在训练成本和…...

VictoriaLogs Syslog日志收集存储系统部署

Docker部署 启动命令 使用以下命令通过Docker启动VictoriaLogs容器: docker run -d --restart always \-p 9428:9428 \-p 514:514/udp \-v ./victoria-logs-data:/victoria-logs-data \--name victoria-logs-syslog-songxwn.com \docker.io/victoriametrics/victor…...

使用 Apache PDFBox 提取 PDF 中的文本和图像

在许多应用中,我们需要从 PDF 文件中提取文本内容和嵌入的图像。为了实现这一目标,Apache PDFBox 是一个非常实用的开源工具库。它提供了丰富的 API,可以帮助我们轻松地读取 PDF 文件、提取其中的文本、图像以及其他资源。 本文将介绍如何使…...

Linux中线程创建,线程退出,线程接合

线程的简单了解 之前我们了解过 task_struct 是用于描述进程的核心数据结构。它包含了一个进程的所有重要信息,并且在进程的生命周期内保持更新。我们想要获取进程相关信息往往从这里得到。 在Linux中,线程的实现方式与进程类似,每个线程都…...

Groovy语言的学习路线

Groovy语言的学习路线 引言 在当前的编程世界中,随着多种编程语言的涌现,开发者常常需要选择合适的语言来满足项目的需求。Groovy语言作为一种动态语言,在Java虚拟机(JVM)环境中得到了广泛使用。它具有简单易用的语法…...

nlf 3d pose 部署学习笔记

目录 multi_hmr创建SemanticRenderer 推理代码 渲染代码: 调用原版render,没成功 用的pose和smlx生成vertices,也有vertices3d hmr2,用的是网络生成的vertices进行渲染。 nlf地址: GitHub - isarandi/nlf: [NeurIPS 2024] Neural Localizer Fields for Continuous …...

【vmware虚拟机安装教程】

以下是在VMware Workstation Pro上安装虚拟机的详细教程: 准备工作 下载VMware Workstation Pro 访问VMware官网下载并安装VMware Workstation Pro(支持Windows和Linux系统)。安装完成后,确保已激活软件(试用版或正式…...

window中git bash使用conda命令

window系统的终端cmd和linux不一样,运行不了.sh文件,为了在window中模仿linux,可以使用gui bash模拟linux的终端。为了在gui bash中使用python环境,由于python环境是在anaconda中创建的,所以需要在gui bash使用conda命…...

PHP语法完全入门指南:从零开始掌握动态网页

本文专为零基础新手设计,通过5000字详细讲解带你系统学习PHP语法。包含环境搭建、基础语法、实战案例,并附20+代码示例。阅读后你将能独立开发简单动态网页! 一、PHP开发环境搭建(新手必看) 1.1 为什么需要搭建环境? PHP是服务器端脚本语言,需要运行在服务器环境中。推…...

什么是蒸馏技术

蒸馏技术(Knowledge Distillation, KD)是一种模型压缩和知识迁移的方法,旨在将一个复杂模型(通常称为“教师模型”)的知识转移到一个小型模型(通常称为“学生模型”)中。蒸馏技术的核心思想是通…...

Python——寻找矩阵的【鞍点】(教师:恒风)

在矩阵中,一个数在所在行中是最大值,在所在列中是最小值,则被称为鞍点 恒风的编程 思路: 使用while循环找到行中最大值,此时列的坐标已知,利用列表推导式生成列不变的纵列,利用min()函数得到纵…...

处理项目中存在多个版本的jsqlparser依赖

异常提示 Correct the classpath of your application so that it contains a single, compatible version of net.sf.jsqlparser.statement.select.SelectExpressionIte实际问题 原因:项目中同时使用了 mybatis-plus 和 pagehelper,两者都用到了 jsqlpa…...

【iOS】包大小和性能稳定性优化

包大小优化 图片 LSUnusedResources 扫描重复的图片 ImageOptim,压缩图片 压缩文件 优化音视频资源 ,使用MP3 代替 WAV ffmpeg -i input.mp3 -b:a 128k output.mp3 视频 H.265(HEVC) 代替 H.264 ffmpeg ffmpeg -i input.mp4 -vcodec lib…...

Delphi语言的软件工程

Delphi语言的软件工程 引言 在软件工程的历史长河中,Delphi语言作为一种快速应用程序开发(RAD)的工具,凭借其高效的开发环境和强大的编程能力,一直在软件开发领域占有一席之地。本文将探讨Delphi语言的历史背景、特性…...

Jenkinsdebug:遇到ERROR: unable to select packages:怎么处理

报错信息: 报错信息解释: musl-1.2.5-r0 和 musl-dev-1.2.5-r1: 这里说明 musl-dev 需要一个特定版本的 musl,即 musl1.2.5-r1,但是当前版本的 musl(1.2.5-r0)并不满足这个条件。版本冲突: 当尝试安装新…...

3、树莓派5 安装VNC查看器 开启VNC服务器

在前序文章中( 2、树莓派5第一次开机),可以使用三种方式开机,其中使用网线及wifi的方式均需要使用到VNC查看器进行远程桌面控制,本文将介绍如何下载安装并配置及使用VNC查看器及服务器,对前序文章做一些补充…...

数据结构——单向循环链表、双链表、双向循环链表

目录 一、单向循环链表 1.1 单向循环链表的概念 1.2 单向循环链表的操作 1.2.1 单向循环链表的创建 1.2.2 单向循环链表的头插 1.2.3 单向循环链表的遍历 1.2.4 单向循环链表的头删 1.2.5 单向循环链表的尾插 1.2.6 单向循环链表的尾删 1.2.7 约瑟夫环 1.3 单向循环列表所有程…...

冒险岛079 V8 整合版源码搭建教程+IDEA启动

今天教大家来部署下一款超级怀旧游戏冒险岛,冒险岛源码是开源的,但是开源的代码会有各种,本人进行了加工整合,并且用idea进行了启动测试,经过修改后没有任何问题。 启动截图 后端控制台 前端游戏界面 声明 冒险岛源码…...

Qwen2-VL 的重大省级,Qwen 发布新旗舰视觉语言模型 Qwen2.5-VL

Qwen2.5-VL 是 Qwen 的新旗舰视觉语言模型,也是上一代 Qwen2-VL 的重大飞跃。 Qwen2.5-VL主要特点 视觉理解事物:Qwen2.5-VL不仅能够熟练识别花、鸟、鱼、昆虫等常见物体,而且还能够分析图像中的文本、图表、图标、图形和布局。 代理性&…...

详解CountDownlatch

引言 CountDownLatch 是 Java 并发包 java.util.concurrent 中的一个同步工具类,由著名的并发编程大师 Doug Lea 所开发。它允许一个或多个线程等待其他线程完成操作后再继续执行,其核心思想是通过一个计数器,对计数器进行调度来实现 原理 …...

STM32外设SPI FLASH应用实例

STM32外设SPI FLASH应用实例 1. 前言1.1 硬件准备1.2 软件准备 2. 硬件连接3. 软件实现3.1 SPI 初始化3.2 QW128 SPI FLASH 驱动3.3 乒乓存储实现 4. 测试与验证4.1 数据备份测试4.2 数据恢复测试 5 实例5.1 参数结构体定义5.2 存储参数到 SPI FLASH5.3 从 SPI FLASH 读取参数5…...