本章重点讨论解锁操作问题。案例使用RedisTemplate完成redis操作。
1.简单加解解锁
@Resource
private RedisTemplate<String, String> redisTemplate;
public void testLock(){
String key= "xx_lock";
String uuid = UUID.randomUUID().toString();
try {
boolean lock = redisTemplate.opsForValue().setIfAbsent(key, uuid, 180, TimeUnit.SECONDS);
if (lock) {
// dosometing
}
} finally {
redisTemplate.delete(key);
}
}
存在问题:超时解锁删除掉目前有效锁(误删其他锁)。
2.持有的锁判断删除
if (redisTemplate.opsForValue().get(key).equals(uuid)) {
redisTemplate.delete(key);
}
存在问题:非原子操作,并发情况删除当前有效锁。
3.DefaultRedisScript原子查删操作
3.1 编写Script
String defaultAtomDelScript = "if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end";
3.2原子删除
redisTemplate.execute(new DefaultRedisScript<Long>(defaultAtomDelScript , Long.class), Arrays.asList(key), uuid);