Redis实现
redis实现主要利用 SET key value NX PX expiretimeMs命令,有一些点可能导致锁的使用错误,值得注意
- 解锁时先检查Redis value值是否与加锁时设定值相等,然后删除key,避免错误地将B的锁释放,使用lua脚本保证原子性。
- expiretime要足够长,避免A获得锁但还没执行完成,锁却自动失效,B获得锁后导致资源竞争
- redis主从同步是异步的,主机故障自动切换时,在从机未完成同步数据时,B可以加锁成功
大多数语言已有的实现可以参考 https://redis.io/topics/distlock
Mysql实现
Mysql实现主要利用表的Unique Key约束。
https://github.com/iccolo/mysql-lock/blob/master/doc/table.md 的实现具备特性:
- 获取锁时忽略已过期的锁
- 不同于redis锁只能被一个任务获取,该实现可以指定能同时获得锁的最大任务数