从银行转账失败到分布式事务:总结与思考
从银行转账失败到分布式事务总结与思考引言在日常生活中银行转账失败并不罕见。你可能遇到这样的情况转出账户扣款成功但转入账户迟迟未到账。这种看似简单的“扣款成功但到账失败”现象背后隐藏着分布式系统中数据一致性的核心难题。从单体架构到微服务、从单机事务到分布式事务技术演进的过程本质上是对“正确性”与“可用性”之间的平衡。本文将从银行转账失败的场景出发深入剖析分布式事务的原理并提供可运行的代码示例带你理解如何设计一个可靠的转账系统。## 银行转账的“朴素”实现为什么它不可靠假设你正在设计一个简单的银行转账系统。最直接的思路是在数据库中对两个账户进行更新操作。例如用 Python 模拟一个单机事务pythonimport sqlite3def transfer(from_account, to_account, amount): conn sqlite3.connect(bank.db) cursor conn.cursor() try: # 开始事务 cursor.execute(BEGIN TRANSACTION) # 从源账户扣款 cursor.execute(UPDATE accounts SET balance balance - ? WHERE id ?, (amount, from_account)) # 检查扣款后余额是否不足模拟业务校验 cursor.execute(SELECT balance FROM accounts WHERE id ?, (from_account,)) if cursor.fetchone()[0] 0: raise Exception(Insufficient balance) # 向目标账户加款 cursor.execute(UPDATE accounts SET balance balance ? WHERE id ?, (amount, to_account)) # 提交事务 conn.commit() print(Transfer success) except Exception as e: # 回滚事务 conn.rollback() print(fTransfer failed: {e}) finally: conn.close()这段代码在单机数据库环境中是可靠的因为事务保证了 ACID原子性、一致性、隔离性、持久性。然而当系统分布到多个服务例如账户服务、通知服务、审计服务时问题就出现了。如果扣款成功但通知服务宕机用户可能以为转账失败而重复操作导致数据不一致。这就是分布式事务要解决的核心问题。## 分布式事务的挑战CAP 理论与最终一致性在分布式系统中我们无法同时满足一致性、可用性和分区容忍性CAP 理论。银行转账场景通常要求强一致性即“扣款成功”与“加款成功”必须同时发生或同时回滚。但网络分区如服务宕机不可避免因此需要引入分布式事务协议。常见的分布式事务模型包括-2PC两阶段提交在协调者与参与者之间分阶段征询和提交但存在阻塞问题和单点故障风险。-TCCTry-Confirm-Cancel业务层面的补偿机制通过预留资源、确认操作、取消操作来实现最终一致性。-Saga长事务将大事务拆分为多个本地事务通过补偿事务Undo处理失败情况。下面以 Saga 模式为例用 Python 模拟一个跨服务的转账流程。## 实战用 Saga 模式实现分布式转账Saga 的核心思想是每个操作都有对应的补偿操作。当某个步骤失败时事务管理器会依次执行之前的补偿操作来撤销已执行的动作。以下是一个简化的实现pythonimport timefrom typing import Dict, List, Callableclass SagaTransaction: def __init__(self): self.steps: List[Dict[str, Callable]] [] def add_step(self, action: Callable, compensate: Callable): 添加一个步骤action 为正常操作compensate 为补偿操作 self.steps.append({action: action, compensate: compensate}) def execute(self): 执行 Saga 事务 executed [] # 记录已成功执行的步骤索引 for i, step in enumerate(self.steps): try: step[action]() executed.append(i) print(fStep {i} executed successfully) except Exception as e: print(fStep {i} failed: {e}) # 回滚已执行的操作 for j in reversed(executed): try: self.steps[j][compensate]() print(fCompensated step {j}) except Exception as comp_error: print(fCompensate for step {j} failed: {comp_error}) return False return True# 模拟账户服务状态account_balances {A: 1000, B: 0}def debit(from_id, amount): 扣款操作 if account_balances[from_id] amount: raise Exception(Insufficient balance) account_balances[from_id] - amount print(fDebited {amount} from {from_id})def compensate_debit(from_id, amount): 扣款的补偿操作加回金额 account_balances[from_id] amount print(fCompensated: added {amount} back to {from_id})def credit(to_id, amount): 加款操作模拟可能失败的情况 # 假设加款服务有 50% 概率失败 if time.time() % 2 0: raise Exception(Credit service unavailable) account_balances[to_id] amount print(fCredited {amount} to {to_id})def compensate_credit(to_id, amount): 加款的补偿操作扣除金额 account_balances[to_id] - amount print(fCompensated: deducted {amount} from {to_id})# 构建 Saga 事务saga SagaTransaction()saga.add_step( actionlambda: debit(A, 100), compensatelambda: compensate_debit(A, 100))saga.add_step( actionlambda: credit(B, 100), compensatelambda: compensate_credit(B, 100))# 执行success saga.execute()print(fTransaction {succeeded if success else failed})print(fFinal balances: A{account_balances[A]}, B{account_balances[B]})运行这段代码你会看到如果扣款成功但加款失败系统会自动触发补偿操作将扣款回滚从而保证最终一致性。注意Saga 模式属于“最终一致性”而非“强一致性”因为补偿操作本身也可能失败需要结合重试、幂等性设计来完善。## 深入原理2PC 与 TCC 的对比### 两阶段提交2PC2PC 通过协调者Coordinator和参与者Participant之间的两次交互来实现原子性-准备阶段协调者询问所有参与者是否准备好提交。参与者需要锁定资源并返回“是/否”。-提交阶段如果所有参与者都同意协调者发送提交指令否则发送回滚指令。2PC 的缺点在于参与者锁定资源期间会阻塞其他事务且协调者是单点故障。如果协调者宕机参与者可能一直处于锁定状态。### TCC 模式TCCTry-Confirm-Cancel是一种业务层面的 2PC 变种-Try预留业务资源如锁定账户资金。-Confirm确认执行业务如实际转账。-Cancel取消预留资源如释放锁定。TCC 避免了 2PC 的数据库锁问题但要求业务接口支持幂等性因为网络重试可能导致重复操作。例如转账的 Try 阶段将资金从可用余额转移到冻结余额Confirm 阶段将冻结余额转移到目标账户Cancel 阶段将冻结余额归还。## 总结从银行转账失败的简单场景出发我们看到了分布式事务并非银弹。2PC 提供强一致性但牺牲了性能和可用性Saga 和 TCC 通过补偿机制实现最终一致性但要求业务逻辑精心设计。在实际系统中需要根据业务场景权衡-金融交易如转账、支付通常要求强一致性可考虑 2PC 或 TCC但需做好超时和重试。-订单系统如下单、扣库存适合 Saga允许短暂不一致通过异步补偿恢复。-日志、通知等非关键操作可以接受最终一致性甚至使用消息队列幂等性设计。分布式事务的实践本质是“权衡”——通过牺牲部分性能或一致性换取系统的可用性和扩展性。没有完美的方案只有最适合当前场景的设计。希望本文能帮助你从原理到实践更清晰地理解分布式事务的本质。

相关新闻

Django毕设选题推荐:基于 Django 的高校荣誉奖项信息化管理平台设计实现 学生获奖信息收录与证书管理系统【附源码、mysql、文档、调试+代码讲解+全bao等】

Django毕设选题推荐:基于 Django 的高校荣誉奖项信息化管理平台设计实现 学生获奖信息收录与证书管理系统【附源码、mysql、文档、调试+代码讲解+全bao等】

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/26 17:10:06 阅读更多 →
Python计算机毕设之基于 Web 的适老化健康守护预警系统 基于 Python 的老年人健康状态追踪与异常告警管理系统(完整前后端代码+说明文档+LW,调试定制等)

Python计算机毕设之基于 Web 的适老化健康守护预警系统 基于 Python 的老年人健康状态追踪与异常告警管理系统(完整前后端代码+说明文档+LW,调试定制等)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/26 17:09:06 阅读更多 →
Python计算机毕设之基于 Django 的音乐发布与社区交流系统 智能音乐推荐与好友分享平台设计(完整前后端代码+说明文档+LW,调试定制等)

Python计算机毕设之基于 Django 的音乐发布与社区交流系统 智能音乐推荐与好友分享平台设计(完整前后端代码+说明文档+LW,调试定制等)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/26 17:09:06 阅读更多 →

最新新闻

F3D:极速轻量的三维查看器完整指南

F3D:极速轻量的三维查看器完整指南

F3D:极速轻量的三维查看器完整指南 【免费下载链接】f3d Fast and minimalist 3D viewer. 项目地址: https://gitcode.com/GitHub_Trending/f3/f3d 您是否曾经因为打开一个3D模型而等待数分钟?或者因为复杂的3D软件界面而感到困惑?F3D…

2026/7/26 17:27:14 阅读更多 →
100个年入十万美金博客的死亡样本:巨头掀翻棋盘,“零点击时代”清算开始

100个年入十万美金博客的死亡样本:巨头掀翻棋盘,“零点击时代”清算开始

博客大崩溃:100个成功博客都发生了什么?[研究]我追踪了100个曾经成功的博客长达四年,以了解谷歌“实用内容更新”和人工智能概览兴起后博客的命运。结果令人震惊:博客的自然流量中位数下降了85%,而只有21个博客的流量持…

2026/7/26 17:27:14 阅读更多 →
DSP/BIOS PIP模块深度解析:生产者-消费者模型与实时数据流管理

DSP/BIOS PIP模块深度解析:生产者-消费者模型与实时数据流管理

1. 项目概述:理解DSP/BIOS中的管道通信在嵌入式实时系统开发,尤其是基于德州仪器(TI)数字信号处理器(DSP)的项目中,任务间的数据高效、安全传递是架构设计的核心挑战。想象一下一个音频处理系统…

2026/7/26 17:27:14 阅读更多 →
云原生架构:从“买房子“到“租公寓“

云原生架构:从“买房子“到“租公寓“

云原生架构:从"买房子"到"租公寓" 买房子的烦心事太多了:首付、月供、装修、维修、物业…有一天你突然想明白了——我为什么要买?租公寓不香吗?想换城市就换城市,想换大房子就换大房子。 云原生就是软件世界的"租公寓"思维。 什么是云原…

2026/7/26 17:27:14 阅读更多 →
Spring AI(7) :哄哄模拟器-提示词工程和实战游戏

Spring AI(7) :哄哄模拟器-提示词工程和实战游戏

本章代码已分享至Gitee:https://gitee.com/lengcz/ai-study.git 文章目录哄哄模拟器-提示词工程1. 清晰明确的指令2. 使用分割符标记输入3. 按步骤拆解复杂任务4. 提供输入输出示例(Few-shot)5. 明确要求输出格式6. 给模型设定一个角色综合实战示例&…

2026/7/26 17:27:14 阅读更多 →
Claude Code:重新定义终端开发的AI编码助手新范式

Claude Code:重新定义终端开发的AI编码助手新范式

Claude Code:重新定义终端开发的AI编码助手新范式 【免费下载链接】fresh-start The original nirholas/claude-code before DMCA and take down. Once everything is cleared, it will return. Working with Anthropic and Github to get everything back. 项目地…

2026/7/26 17:26:14 阅读更多 →

日新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/26 0:00:31 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/26 0:00:31 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/26 0:00:31 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/26 0:00:31 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/26 0:00:31 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/26 0:00:31 阅读更多 →

月新闻