【分布式锁思想集合】

微服务分布式锁思想集合

  1. 基于扣减库存演示超卖,使用分布式锁解决这种超卖的情况
  2. 使用nginx做负载均衡、使用jmeter做压力测试
  3. 环境要求:jdk1.8+、maven3.x
  4. 技术要求:SpringBoot2.x、Springmvc、spring、mybatis、springData-redis、mysql、
    redis
  5. 开发工具:idea、nginx、jmeter
  6. 其他: zookeeper、lua脚本等

1. 传统锁

JVM本地锁(synchronized、ReentrantLock)

2.基于redis的分布式锁

redis乐观锁

  • 手写实现
    • 基本实现
    • 防死锁
    • 防误删
    • 可重入
    • 可续期
    • 红锁算法
  • Redisson框架
    • 可重入锁及源码分析
    • 公平锁FairLock
    • 联锁、红锁
    • 读写锁
    • 信号量
    • 闭锁

3.基于zk的分布式锁

  • 手写实现
    • Zookeeper的安装
    • 常用指令及Java客户端
    • 基本实现分布式锁
    • 实现阻塞锁
    • 实现可重入式分布式锁
  • Curator框架
    • 可重入锁及源码解读
    • 可重入的读写锁
    • 信号量
    • 栅栏
    • 共享计数器

4.基于mysql的分布式锁

一句sql扣减库存

update stock set count = count -1 where product_code = '1001' and count >= 1

这个update语句会自动加锁,这是靠数据库引擎的(表锁)

优点:

  1. 数据库引擎加锁执行更新保证了服务集群不会出现超卖现象
  2. 吞吐量也会很高

缺点:

  1. 锁范围的问题(表锁、行锁)
  2. 同一商品有多条库存记录
  3. 无法记录库存变化前后的状态

Mysql悲观锁:

select ... for update

  1. 查询并锁定信息
java 复制代码
@select("select * from db_stock where product_code = #{productCode} for update")
List<Stock> queryStock(String productCode);
List<Stock> stocks = this.stockMapper.queryStock("1001");
Stock stock = stocks.get(0);
  1. 判断库存充足
java 复制代码
if(stock != null && stock.getCount >0) {
   stock.setCount(stock.getCount -1);
   this.stockMapper.updateById(stock);
}
  1. 扣减库存
    配和事务注解@Transational

4.1 mysql悲观锁中使用行级锁

python 复制代码
# 1.锁的查询或者更新条件必须是索引字段
# 2.查询或更新条件必须是具体值(可以是in,= 但不能是!=,like)

4.2 mysql

java 复制代码
/*
1. jvm本地锁:三种情况导致锁失效 600
	多例模式
	事务 Read Uncommitted
	集群部署
2. 一个sql语句:更新数量时判断 2000
	解决:三个锁失效
	问题:
		1. 锁范围问题 表级锁 行级锁
		2. 同一个商品有多条库存记录
		3. 无法记录库存变化前后的状态
3. 悲观锁:select ... for update 
	问题:
		1. 性能问题
		2. 死锁问题:对多条数据加锁时,加锁数据一致。
			①事务,对第一条数据加锁,请求第二条数据的锁;
			②事务,对第二天数据加锁,请求第一条数据的锁;
			两个事务争抢对方的锁,造成死锁问题。
		3. 库存操作要统一:select..for update  普通的select
4. 乐观锁:时间戳 version版本号 CAS机制
	问题:
		1.高并发情况下,性能极低
		2.ABA问题
		3.读写分离情况下乐观锁不可靠(主从数据库 数据拷贝的原因)
总结:
	性能:一个sql > 悲观锁 > jvm锁 > 乐观锁
	如果追求极致性能,业务场景简单并且不需要记录数据变化前后的情况下:
		优先选择:一个sql
	如果写并发量较低(多读),争抢不是很激烈的情况下优先选择:乐观锁
	如果写并发量较高,一般会经常冲突,此时选择乐观锁的话,会导致业务代码不间断的重试。
		优先选择:mysql悲观锁
	不推荐jvm本地锁。
*/
相关推荐
风吹夏回7 天前
RabbitMQ 核心术语 + Python pika 方法完整讲解
分布式·python·rabbitmq
风吹夏回7 天前
RabbitMQ 三种模式入门:HelloWorld、WorkQueue、PubSub
分布式·rabbitmq·ruby
霸道流氓气质7 天前
分布式追踪与 RequestId 传播完全指南
分布式
cheems95277 天前
[RabbitMQ高级特性] 消息确认机制:从 Ready / Unacked 到 basicAck、basicReject、basicNack 的底层拆解
分布式·rabbitmq·ruby
枫华落尽7 天前
【Hadoop01-完全分布式运行模式】
分布式
隔壁阿布都7 天前
ShedLock 分布式定时任务锁框架介绍
spring boot·分布式
文艺倾年7 天前
【强化学习】数学推导专题,20W字总结(十五)
人工智能·分布式·大模型·强化学习·vibecoding
ACP广源盛139246256737 天前
GSV9001S@ACP#1080P 级视频处理芯片,物理 AI 普及终端的高性价比选择
大数据·人工智能·分布式·嵌入式硬件·spark
guslegend7 天前
第1章:初始Kafka
分布式·kafka
ACP广源盛139246256738 天前
GSV5600@ACP#多接口协议转换芯片,物理 AI 便携终端的互联核心
大数据·人工智能·分布式·嵌入式硬件·spark