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

分布式事务原理(高并发系统下的数据一致性保障)

事务:对数据库的一批操作增删改(写操作)  @Transactional

为什么需要分布式事务?

分布式事务的核心目的是在跨服务、跨数据库、跨网络的分布式系统中,确保多个独立操作要么全部成功,要么全部失败,从而维护数据一致性。

一、分布式事务的根源:架构拆分带来的挑战
1. 微服务架构
- 业务被拆分为多个独立服务(如订单、库存、支付),每个服务有私有数据库。  
- 本地事务失效:单个服务的数据库事务无法跨服务边界(例如:订单库的事务不能控制支付库的回滚)。  

2. 数据库分片/分库分表
- 单表数据拆分到不同数据库节点(如用户表按ID分库),一次操作可能涉及多个节点。  
- 示例:转账时,付款方和收款方账户位于不同分片,需保证两边余额同步更新。

3. 跨资源类型操作
- 同时操作数据库、消息队列、缓存等异构系统(如:扣款(DB)后发消息(Kafka)需保证原子性。

二、、分布式事务的核心需求
1. 原子性(Atomicity)
- 所有参与方必须达成一致提交或回滚,避免部分成功。  

2. 最终一致性(Eventual Consistency)
- 允许短暂不一致,但需通过补偿(如重试、冲正)最终达成一致。  

3. 隔离性(Isolation)
- 防止并发操作导致中间状态被误读(如:读到未提交的脏数据)。  

三、何时需要分布式事务?

强一致性场景:金融转账、库存扣减、机票订座。  
弱一致性可替代场景:可考虑异步通知+对账(如物流状态更新)。  


分布式事务是分布式系统在拆分架构异构资源下维持数据一致性的必要手段,但需根据业务场景权衡一致性、性能和复杂度。

CAP理论(分布式事务中不可能的三角)

  • 一致性C(要么全部成功,要么全部失败)强一致性、最终一致性
  • 可用性A(出错系统是否还可用)
  • 分区容错性P(在不同的服务上数据是否一样)

分布式事务原则

  • 尽量避免分布式事务
  • 服务要高内聚、低耦合
  • 服务粒度不宜太小
  • 服务边界即业务边界(康威定律)
  • 最终一致性vs强一致性
分布式锁

并发操作(竞争问题 Race Condtition)

方案一:“库存”字段 加锁

方案二:SKU->记录->购买记录(Unique key = SKU记录)数据库的唯一索引保证不会超卖

乐观锁

假定大部分情况下都不会有锁冲突

实现方式:update 带版本号/时间戳,WATCH命令、synchronized

悲观锁

假定大部分情况下都会有冲突

实现方式:SELECT ... FOR UPDATE,SETNX + EXPIRE

Redisson悲观锁
  • Redis锁操作实现比较复杂
  • 减少重复代码
  • Redis库
RLock lock = redisson.getLock("goods" + goodsId);
try {// 加锁,默认30秒超时,支持自动续期lock.lock();// 或者指定超时时间// lock.lock(10, TimesUnit.SECONDS);
} finally {//释放锁lock.unlock();
}
Redisson公平锁 (先来的先得到)
RLock fairLock = redisson.getFairLock("myFairLock");
try {fairLock.lock();// 执行业务逻辑// ...
} finally {fairLock.unlock();
}

Redisson乐观锁

RBUcket<MyObject> bucket = redisson.get("myObject");
RAtomicLong version = redisson.getAtomicLong("myObject:version");// 读取数据
MyObject obj = bucket.get();
long currentVersion = version.get();// 修改数据
obj.setSomeField("new value");// 尝试更新
boolean updated = bucket.compareAndSet(obj, newObj);
if(!updated) {//版本冲突,处理冲突逻辑//...
}

注意事项

1.锁超时:总是设置合理的锁超时时间,避免死锁

2.异常处理:确保在finally块中释放锁

3.锁续期: Redisson默认支持锁续期(看门狗机制)

4.网络问题:考虑Redis 集群故障时的处理策略

5.性能影响:分布式锁会影响性能,只在必要时使用

最佳实践

  • 读多写少:乐观锁
  • 写多读少:悲观锁
  • 尽量减少锁的持有时间
消息队列

Tell Don't Ask  天然事务边界

高内聚/低耦合

高内聚

  • 同一个业务放在一个服务里
  • 使用数据库控制业务内事务

低耦合

  • 不同业务放到不同的服务
  • 使用消息队列传递事件
  • 通过同步接口查询数据

分布式框架SEATA

http://www.dtcms.com/a/325017.html

相关文章:

  • 一、线性规划
  • 免费数字人API开发方案
  • 高精度计算+快速幂算法
  • 【算法题】:斐波那契数列
  • 【langchain】如何给langchain提issue和提pull request?
  • SpringIoc 实践和应用--XML配置
  • 数据结构-deque(双端队列)和queue(队列)区别
  • Flask多进程数据库访问问题详解
  • spring全家桶使用教程
  • Lua语言元表、协同程序
  • 密码学的数学基础2-Paillier为什么产生密钥对比RSA慢
  • SQL三剑客:DELETE、TRUNCATE、DROP全解析
  • 深度相机---双目深度相机
  • 浏览器CEFSharp+X86+win7 之 浏览器右键菜单(六)
  • Mysql笔记-存储过程与存储函数
  • vulnhub-doubletrouble靶场攻略
  • Linux C文件操作函数
  • 谷歌DeepMind发布Genie 3:通用型世界模型,可生成前所未有多样化的交互式虚拟环境
  • C++移动语义、完美转发及编译器优化零拷贝
  • PostgreSQL 批量COPY导入优化参数配置
  • 近红外与可见光图像融合的多种方法实现
  • OpenAI正式发布GPT-5:迈向AGI的关键一步
  • Java基础-多线程
  • lesson34:深入理解Python线程:从基础到实战优化
  • hysAnalyser --- 支持文件转播UDP/RTP实时流功能
  • CompletableFuture实现Excel 多个sheet页批量导出
  • 【数据分析】循环移位岭回归分析:光遗传学冻结行为模式研究
  • 【PyTorch】单目标检测项目部署
  • MPLS的基本工作原理
  • AI玩具新浪潮:百亿资本涌入,情感计算重塑陪伴经济