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

什么是分布式事务?

分布式事务是指涉及多个独立的服务或资源的事务。这些服务或资源可能位于不同的服务器、数据库或其他系统上。分布式事务的目标是确保所有参与的操作要么全部成功(提交),要么全部失败(回滚),以维护数据的一致性和完整性。

与本地事务的区别:

  • 本地事务 (Local Transaction): 通常指单个数据库中的事务,由数据库管理系统 (DBMS) 保证 ACID 特性(原子性、一致性、隔离性、持久性)。
  • 分布式事务 (Distributed Transaction): 涉及多个数据库、消息队列、服务等,需要跨越多个系统来保证 ACID 特性。

为什么需要分布式事务?

在微服务架构、SOA (Service-Oriented Architecture) 或分布式系统中,一个业务操作可能需要调用多个服务或操作多个数据库。如果其中一个服务或数据库操作失败,而其他操作成功,就会导致数据不一致。分布式事务就是为了解决这个问题,确保多个操作的原子性。

举例:

一个典型的电商场景:用户下单。这个操作可能涉及:

  1. 订单服务: 创建订单。
  2. 库存服务: 扣减库存。
  3. 支付服务: 发起支付。

如果以上三个服务分别部署在不同的服务器上,并且使用不同的数据库,那么就需要使用分布式事务来保证这三个操作要么全部成功,要么全部失败。例如,如果库存扣减成功,但支付失败,那么就需要回滚库存的扣减,否则就会出现超卖的情况。

分布式事务的挑战:

  • 网络延迟和故障: 分布式系统中的网络通信可能存在延迟、丢包、超时等问题,增加了事务管理的复杂性。
  • 异构系统: 不同的服务可能使用不同的数据库、消息队列或其他技术,增加了协调的难度。
  • 性能开销: 分布式事务通常需要额外的协调机制,可能会降低系统的性能。
  • 复杂性: 分布式事务的实现比本地事务复杂得多,需要考虑各种异常情况和容错机制。

常见的分布式事务解决方案:

  1. 两阶段提交 (2PC, Two-Phase Commit):

    • 一种经典的分布式事务协议,分为两个阶段:
      • 准备阶段 (Prepare Phase): 协调者 (Coordinator) 向所有参与者 (Participant) 发送准备请求,询问是否可以提交事务。参与者执行事务操作,但不提交,并向协调者发送响应(同意或拒绝)。
      • 提交阶段 (Commit Phase): 如果所有参与者都同意提交,协调者向所有参与者发送提交请求,参与者提交事务。如果任何一个参与者拒绝提交,协调者向所有参与者发送回滚请求,参与者回滚事务。
    • 优点: 强一致性。
    • 缺点: 性能较差(阻塞协议,同步等待),存在单点故障(协调者),可能发生数据不一致(协调者故障,部分参与者未收到提交/回滚请求)。
  2. 三阶段提交 (3PC, Three-Phase Commit):

    • 2PC 的改进版,增加了预提交阶段 (PreCommit Phase),减少了阻塞时间。
    • CanCommit 阶段: 类似于 2PC 的准备阶段。
    • PreCommit 阶段: 协调者在所有参与者都同意提交的情况下, 发送 PreCommit 请求, 参与者执行事务操作,但不提交.
    • DoCommit 阶段: 如果所有参与者都响应了 PreCommit 请求, 协调者发送 DoCommit 请求, 参与者提交事务. 否则, 发送回滚请求.
    • 优点: 降低了阻塞范围, 避免了协调者故障导致的数据不一致.
    • 缺点: 实现复杂,性能仍然不高。
  3. TCC (Try-Confirm-Cancel):

    • 一种补偿型事务,分为三个阶段:
      • Try: 尝试执行业务操作,预留资源。
      • Confirm: 确认执行业务操作,提交事务。
      • Cancel: 取消执行业务操作,释放预留资源,回滚事务。
    • 优点: 性能较好(异步非阻塞),适用于各种场景。
    • 缺点: 需要业务代码实现 Try、Confirm、Cancel 三个接口,增加了开发成本。需要考虑幂等性、空回滚、悬挂等问题。
  4. Saga:

    • 将长事务拆分成多个短事务,每个短事务由一个服务执行。
    • 每个短事务都有一个对应的补偿操作(回滚操作)。
    • 如果任何一个短事务失败,Saga 协调器会执行之前已完成的短事务的补偿操作,以实现最终一致性。
    • 优点: 性能较好,适用于长事务和复杂业务流程。
    • 缺点: 不保证隔离性,可能需要处理并发问题。
  5. 本地消息表 (Local Message Table):

    • 将业务操作和消息发送操作放在同一个本地事务中。
    • 业务操作成功后,消息被写入本地消息表,但不立即发送。
    • 使用一个定时任务或其他机制,扫描本地消息表,将消息发送到消息队列。
    • 消费者消费消息,执行相应的业务操作。如果消费失败,可以重试。
    • 优点: 实现简单,可靠性较高。
    • 缺点: 需要额外的消息表,增加了数据库的负担。可能存在消息重复消费的问题(需要消费者实现幂等性)。
  6. 可靠消息最终一致性 (Reliable Message Queue):

    • 利用消息队列的可靠性来保证最终一致性。
    • 生产者将消息发送到消息队列,消息队列保证消息至少被投递一次。
    • 消费者消费消息,执行相应的业务操作。如果消费失败,消息队列会重试投递。
    • 优点: 实现简单,性能较高。
    • 缺点: 不保证强一致性,可能存在消息延迟。需要消费者实现幂等性。
  7. 最大努力通知 (Best-Effort Delivery):

    • 业务活动的主动方, 在完成业务处理之后, 向业务活动的被动方发送消息, 尽最大努力将这个消息发送成功.
    • 会提供消息重试机制.
    • 适用于对最终一致性要求不高, 并且业务流程较短的场景.

选择合适的解决方案:

没有一种解决方案可以解决所有分布式事务问题,需要根据具体情况选择合适的解决方案或组合使用多种方案。 需要考虑以下因素:

  • 一致性要求: 需要强一致性还是最终一致性?
  • 性能要求: 对事务的响应时间有什么要求?
  • 系统复杂性: 引入新的组件或架构会增加系统的复杂性。
  • 开发成本: 不同的解决方案开发和维护成本不同。
  • 技术栈: 不同的解决方案可能依赖于特定的技术或框架。

在实践中,对于强一致性要求高的场景,可以考虑 2PC 或 TCC。对于最终一致性要求高的场景,可以考虑 Saga、本地消息表或可靠消息最终一致性。 最大努力通知适用于对一致性要求不高的场景。


http://www.kler.cn/a/564615.html

相关文章:

  • 表格软件推荐:为何选择VeryReport让数据分析和报表生成更高效?
  • React 源码揭秘 | 更新队列
  • Metal学习笔记八:纹理
  • 【MATLAB源码-第268期】基于simulink的永磁同步电机PMSM双闭环矢量控制系统SVPWM仿真,输出转速响应曲线。
  • MySQL 事务笔记
  • openssl的aes128_ECB加密解密运算实例
  • 自动化反编译微信小程序工具-e0e1-wx
  • 基于大数据的去哪儿网景区可视化及协同过滤推荐系统
  • 解锁CSnakes:.NET与Python的融合魔法
  • 事务的隔离级别
  • 深度学习中的 shape以及 axis的含义以及使用
  • java23种设计模式-状态模式
  • vue框架后遗症∶被遗忘的dom操作
  • 蓝耘科技发布DeepSeek满血版:引领AI推理革新,开启智慧新时代
  • 网络通信库
  • 时序论文40 | 将不规则采样时间序列转换为图像,利用预训练视觉Transformer进行分类
  • IO 和 NIO 有什么区别?
  • Linux:Shell环境变量与命令行参数
  • 29.[前端开发-JavaScript基础]Day06-创建对象-对象补充-包装类型-数组Array
  • 神经网络 - 函数饱和性、软性门、泰勒级数