redis分布式锁

简单场景:

单机模式下:添加synchronized实现同步,分布式环境下不能实现同步

redis是单线程

问题:假如执行到stringRedisTemplate.opsForValue().set("stock",realStock+");这行出问题,那么后面的stringRedisTemplate.delete(lockKey);没有执行,则会造成死锁

解决方法:添加try...catch,最后finally的时候一定删除键值,释放锁

问题:假如运维在stringRedisTemplate.opsForValue().set("stock",realStock+");这行代码执行的时候kill程序了,finally里面的释放锁又没有执行,又出现死锁了。

解决方法:key值添加超时时间:

问题:运行Boolean result=stringRedisTemplate.opsForValue().setIfAbsent(lockKey,"zhuge")后,程序挂掉,stringRedisTemplate.expire(lockKey,30,TimeUnit.SECONDS);这行代码没有执行,则又会出现死锁

解决办法:两句合成一句,执行redis的原子操作,对redis版本有要求

问题:设置超时时间10秒,程序运行到stringRedisTemplate.opsForValue().set("stock",realStock+"");花费了10秒

发现锁超时了,容易产生第一个请求会释放第二个请求的锁,第三个请求又能请求了,导致完全没有顺序,造成锁的永久失效

解决办法:问题的本质:自己的锁被别人解锁了;

将value(zhuge)随机,

30秒过期问题,解决:执行代码的时候,开启一个分线程,每过30*1/3=10秒给过期时间续命,复原成30秒,直到删除锁,分线程也删除

上述流程可以使用redisson框架,三行代码

 

 

在redis集群中,可能出现的问题:

master挂掉之后,线程1保留在master上的锁不在新的master里,当又来了一个线程三,获取锁的时候,发现新的master里没有线程1的锁,就获取锁继续运行导致出错。

 

posted @ 2019-07-22 15:00  hotMemo  阅读(229)  评论(0编辑  收藏  举报