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)只允许一个客户端操作共享资源
这种情况下,对共享资源的操作一般是非幂等性操作。在这种情况下,如果出现多个客户端操作共享资源,就可能意味着数据不一致,数据丢失。

posted @ 2021-09-01 10:22  24601  阅读(399)  评论(0编辑  收藏  举报