【分布式锁思想集合】

  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. 查询并锁定信息
@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. 判断库存充足
if(stock != null && stock.getCount >0) {
   stock.setCount(stock.getCount -1);
   this.stockMapper.updateById(stock);
}
  1. 扣减库存
    配和事务注解@Transational

4.1 mysql悲观锁中使用行级锁

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

4.2 mysql

/*
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本地锁。
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值