This repository contains the projects of learning distributed-locks
-
JVM 本地锁
三种情况下会失效:多例模式、事务操作、集群部署
-
MySQL 悲观锁
使用 DML 操作或者 select for update 会触发锁机制
如果是查询或更新索引字段那么会使用行级锁,索引失效时会使用表级锁
适用写并发量较高的情况
-
MySQL 乐观锁
使用版本号机制
适用读多写少,争抢不是很激烈的情况
性能的比较:悲观锁 > JVM 本地锁 > 乐观锁
-
使用 setnx 实现
- 防止死锁:设置过期时间
- 设置过期时间原子性:使用 set key value ex time nx 实现
- 防止误删除:使用 UUID 防止误删
- 自动续期
-
防误删原子性
防误删需要先判断是否自己持有锁,再进行删除。如果在判断后时锁过期,则会导致删除其他线程持有的锁
使用 lua 脚本实现原子操作
在 Redis 中使用 lua 脚本:
EVAL script numkeys key [keys…] arg [args…]
lua 防误删操作:
if (redis.call('get', 'lock') == ARGV[1]) then redis.call('del', 'lock') end