下面就是我自己实现的代码,其中有些地方有些疑惑:
1.线程未执行完代码锁就过期如何避免?
2.当服务宕机后,锁会因过期时间原因直接释放,但是当前服务重启后会出现业务代码未执行完,比如我要添加1条数据,比如一个订单物品的购买时单价,然后再用这个单价去计算总价格再存入数据。在这两个此操作过程中服务挂了怎么办(重启锁也过期了)。
3.redis集群某个节点在枷锁成功后突然宕机了,数据未及时同步给其他节点。
public void redisLock(){
//使用uuid作为唯一值的情况
String uuid=UUID.randomUUID().toString();
String locker="lock";
//对进来的线程进行资源锁定
Boolean lock=redisTemplate.opsForValue().setIfAbsent(locker,uuid,10,TimeUnit.SECONDS);
if (lock){
//加锁成功则执行相应服务
Object value= redisTemplate.opsForValue().get("num");
int num= Integer.parseInt(value+"");
redisTemplate.opsForValue().set("num", String.valueOf(++num));
//获取lua脚本
DefaultRedisScript<Long> defaultRedisScript=new DefaultRedisScript();
defaultRedisScript.setLocation(new ClassPathResource("redisLock.Lua"));
defaultRedisScript.setResultType(Long.class);
//利用脚本进行解锁
redisTemplate.execute(defaultRedisScript,Arrays.asList(locker),uuid);
}else {
try {
Thread.sleep(100);
redisLock();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
这里lua脚本内容
if redis.call('get', KEYS[1]) == ARGV[1]
then return redis.call('del', KEYS[1])
else return 0
end