https://www.tiangua.info/blog/4e409daf-40a1-440e-a94a-f1568e29e9ea
将业务分解之后,分别给锁续期看上去能够解决锁过期问题,但是每个业务续多久时间实际上很难评估,而且需要把续期的代码耦合在业务代码里,可读性非常差,这里就算能够和好的续期,那还是存在其他问题,比如如果一个线程执行的多个方法都要获取同一把锁,setNx 没办法很好的解决
public void doBiz(String skuCode) {
doBiz1(skuCode);
doBiz2(skuCode);
}
public void doBiz1(String skuCode) {
Boolean locked = redisClient.setNx(skuCode, Thread.getId(), 10, TimeUnit.SECONDS);
...
}
public void doBiz2(String skuCode) {
Boolean locked = redisClient.setNx(skuCode, Thread.getId(), 10, TimeUnit.SECONDS);
...
}
一个不完美的解决方案:通过ThreadLocal传递锁的状态到各个栈帧,但是这个有风险,因为判断逻辑和加锁逻辑不是一个原子操作。
public boolean lock(String key, String methodName) {
if (ThreadLocalUtils.getLockKey().equals(key)) {
return true;
}
Boolean locked = redisClient.setNx(skuCode, Thread.getId(), 60, TimeUnit.SECONDS);
ThreadLocalUtils.setLockKey(key);
ThreadLocalUtils.setLockMethod(key, methodName);
}
public boolean unLock(String key, String methodName) {
if (ThreadLocalUtils.getLockKey().equals(key)) {
if (ThreadLocalUtils.getLockMethod().equals(methodName)) {
redisClient.del(key);
}
return true;
}
}