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.调整释放锁位置

经验分享 程序员 微信小程序 职场和发展