redis分布式锁
1.异常
描述
使用的公平锁.开了两个线程,一个线程负责加锁,另一个线程解锁,发生该异常。
相关加锁代码
String redisKey = TrialRedisLockEnum.TRIAL_REDIS_LOCK_ENUM.name().concat(id); RLock locke =redissonClient.getFairLock(redisKey); locke.lock(60 * 60L, TimeUnit.SECONDS);
相关解锁代码
String redisKey = TrialRedisLockEnum.TRIAL_REDIS_LOCK_ENUM.name().concat(id); RLock locke =redissonClient.getFairLock(redisKey); System.out.println(locke.isLocked() + "11" + locke.isHeldByCurrentThread()); locke.unlock();
异常信息
attempt to unlock lock, not locked by current thread by node id: 9f178836-f7e1-44fe-a89d-2db52f399c0d thread-id: 22
2.分析原因
redis分布式锁是锁定的当前线程,如果A线程加锁,那么用unlock()方法只能由当前加锁线程解锁。
3.解决办法
在其他线程解锁时,使用强制解锁locke.forceUnlock(),或者必须当前线程解锁,不要跨线程
String redisKey = TrialRedisLockEnum.TRIAL_REDIS_LOCK_ENUM.name().concat(id); RLock locke = redisService.getLock(redisKey); System.out.println(locke.isLocked() + "11" + locke.isHeldByCurrentThread()); locke.forceUnlock();
4.参考
https://blog.csdn.net/weixin_39619170/article/details/110986437
https://blog.csdn.net/Yunwei_Zheng/article/details/106480759
https://www.cnblogs.com/nov5026/p/11684632.html
https://mp.weixin.qq.com/s?__biz=MzI1NDQ3MjQxNA==&mid=2247486626&idx=1&sn=f8b410dd4d406bdc68c0a063d48b78a3&chksm=e9c5f513deb27c05fc4962b01fea54310dd93447fe7cc260c31eb10ac4e9a0b72f0b61f79820&mpshare=1&scene=1&srcid=1226l2EumUEdJYFH53SJx1S2&sharer_sharetime=1577328331241&sharer_shareid=1cbff4bc02071eab4c6b044454488c83#rd
5.扩展
RLock的lock()方法对于公平锁来说必须由持有锁的线程释放锁,才能得到锁,否者线程一致等待,直到获得锁.两个线程a,b,a加上分布式锁,然后没解锁,b去获得锁,b就会一直等待直到a释放锁,获得锁。
为什么使用分布式锁?
保证分布式系统中的线程按顺序执行任务。同一个方法,多个程序实例。
(1)允许多个客户端操作共享资源
这种情况下,对共享资源的操作一定是幂等性操作,无论你操作多少次都不会出现不同结果。在这里使用锁,无外乎就是为了避免重复操作共享资源从而提高效率。
(2)只允许一个客户端操作共享资源
这种情况下,对共享资源的操作一般是非幂等性操作。在这种情况下,如果出现多个客户端操作共享资源,就可能意味着数据不一致,数据丢失。