Redis分布式锁踩坑记--锁异常释放
1.背景描述:
1.监听到Redis的Key过期,
2.添加分布式锁,
3.根据Key信息,异步执行相应逻辑
4.释放分布式锁
2.异常逻辑
伪代码
public void onListener(String key){
if(!key.contains("mykey"){
return;
}
String random = getrandom();
String idStr = getid();
Boolean flag = redisTemplate.opsForValue().setIfAbsent("REDISEXPIREKEY" + random, id);
if (flag == null || !flag) {
log.info("数据已经被处理 : " + body);
return;
} else {
redisTemplate.expire("REDISEXPIREKEY" + random, 1L, TimeUnit.MINUTES);
}
try {
new Thread(){
....
insert();
....
}
} catch (Exception e) {
log.error("异常", e);
} finally {
String id = redisTemplate.opsForValue().get("REDISEXPIREKEY" + random);
if (idStr.equals(id)) {
redisTemplate.delete("REDISEXPIREKEY" + random);
} else {
Long timeLong = redisTemplate.getExpire("REDISEXPIREKEY" + random);
if (timeLong != null && timeLong <= 0) {
redisTemplate.delete("REDISEXPIREKEY" + random);
}
}
}
}
异常描述:一个Redis的key过期,会插入多条数据
3.异常分析
猜想问题:
Q:Redis的Key过期时间设置异常
A:Redis的Key设置过期时间是10分钟,数据记录时间相差2,3秒。判断和Redis过期时间没关系
2.Redis的Key值使用不当
Q:一顿操作,各种试,没啥效果。(建议Redis的key长度不要过长,不要出现特殊字符)
3.分布式锁过早释放
Q:经过一番论证尝试,确定是这个问题。
加锁->异步逻辑->释放锁
异步,就起个线程毫秒级的事,但是锁释放咯
B、C、D....服务就感觉不到锁存在,太可怕了。。。
4.线程执行异常
Q:就一个入库记录,咋会出问题
4.异常解决
1.去掉异步,同步执行
2.调整释放锁位置
