public boolean lock(String key, String value) {
// 设置锁的过期时间,这里假设过期时间为30秒
long expireTime = 30 * 1000; // 30秒,单位为毫秒
try {
// 尝试获取锁并设置过期时间
Boolean isLock = redisTemplate.opsForValue().setIfAbsent(key, value, expireTime, TimeUnit.MILLISECONDS);
if (isLock != null && isLock) {
return true; // 成功获取锁
}
String currentValue = redisTemplate.opsForValue().get(key);
// 如果锁已经过期
if (!StringUtils.isEmpty(currentValue) && Long.valueOf(currentValue) < System.currentTimeMillis()) {
// 使用 Lua 脚本保证原子性
String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('set', KEYS[1], ARGV[2]) else return nil end";
DefaultRedisScript<String> redisScript = new DefaultRedisScript<>(script, String.class);
String result = redisTemplate.execute(redisScript, Collections.singletonList(key), value, Long.toString(System.currentTimeMillis() + expireTime));
if ("OK".equals(result)) {
log.info("锁过期并重新加锁成功");
return true;
}
}
} catch (Exception e) {
log.error("加锁异常", e);
}
return false;
}
redis分布式锁的实现方式之一+lua脚本保证操作的原子性
最新推荐文章于 2024-07-29 13:42:38 发布