分布式锁是在分布式环境下用于解决资源并发访问冲突的技术和方法,有多种实现方式。每种实现方式有自身的优势和不足,需要根据项目的实际场景和需求进行选择使用。
1. 数据库实现
(1)利用唯一索引或者主键唯一性,添加记录成功表示获取锁成功;
(2)死锁问题,删除锁,超时的锁,可以采用定时任务删除过期锁;
(3)非阻塞锁,获取失败时,需要有重试机制(参考自旋锁);
(4)可重入设计,记录线程标识,如果是自身,则可以进入,特别是在递归调用;
(5)单点故障;
(6)并发访问性能受限;
可以看出,使用数据库实现分布式锁存在比较多的明显缺点,不是一个完善的方案,好处是在一些访问并发要求不高的场景,使用这种方式,不需要依赖更多的第三方组件。
2. redis实现
(1)锁过期时间设置问题,时间太短任务没完成,锁被释放了;时间太长,出现异常了,但是没有及时释放锁;
(2)释放锁的时候,只能释放自己加的锁,不能释放别人加的锁;总是执行释放锁,需要判断锁的所有者是否是自己;
(3)锁未设置超时,导致死锁问题;
(4)锁的粒度,应该根据业务需要,尽力缩小锁的范围;
可以看出,如果直接使用redis实现分布式锁,技术上是可行的,只是还存在一些特殊场景需要考虑和处理,不然在并发性能高的场景,可能存在各种问题,比如锁过期时间长度设置太短,释放了另外线程添加的锁等。
3. redisson实现
redisson是在redis的基础上完善而来的,对分布式锁有比较完善的支持,在条件允许的情况下,尽量使用此类比较完善的框架来实现,使用经过广泛验证的框架,比自己造轮子更合适。