修改多节点同时执行任务情况
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
package com.ruoyi.common.core.redis;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.connection.ReturnType;
|
||||
import org.springframework.data.redis.core.RedisCallback;
|
||||
import org.springframework.data.redis.core.script.DefaultRedisScript;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -76,10 +78,10 @@ public class DistributedLockUtil {
|
||||
* 自定义参数获取锁
|
||||
*/
|
||||
public String acquireLockWithRenewal(String lockKey, long expireSeconds, long acquireTimeoutSeconds) {
|
||||
String identifier = UUID.randomUUID().toString();
|
||||
long endTime = System.currentTimeMillis() + acquireTimeoutSeconds * 1000;
|
||||
|
||||
while (System.currentTimeMillis() < endTime) {
|
||||
String identifier = UUID.randomUUID().toString();
|
||||
boolean locked = tryLockOnce(lockKey, identifier, expireSeconds);
|
||||
if (locked) {
|
||||
startRenewal(lockKey, identifier, expireSeconds);
|
||||
@@ -116,14 +118,31 @@ public class DistributedLockUtil {
|
||||
/**
|
||||
* 尝试获取一次锁
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private boolean tryLockOnce(String lockKey, String identifier, long expireSeconds) {
|
||||
try {
|
||||
if (!redisCache.hasKey(lockKey)) {
|
||||
redisCache.setCacheObject(lockKey, identifier, (int) expireSeconds, TimeUnit.SECONDS);
|
||||
String storedId = redisCache.getCacheObject(lockKey);
|
||||
return identifier.equals(storedId);
|
||||
String lua = "if redis.call('setnx', KEYS[1], ARGV[1]) == 1 then "
|
||||
+ "redis.call('expire', KEYS[1], ARGV[2]) "
|
||||
+ "return 1 "
|
||||
+ "else "
|
||||
+ "return 0 "
|
||||
+ "end";
|
||||
|
||||
// 执行Lua脚本
|
||||
Object result = redisCache.redisTemplate.execute(
|
||||
(RedisCallback<Object>) connection -> {
|
||||
byte[] script = lua.getBytes();
|
||||
byte[] key = redisCache.redisTemplate.getStringSerializer().serialize(lockKey);
|
||||
byte[] val = redisCache.redisTemplate.getStringSerializer().serialize(identifier);
|
||||
byte[] exp = String.valueOf(expireSeconds).getBytes();
|
||||
return connection.eval(script, ReturnType.INTEGER, 1, key, val, exp);
|
||||
}
|
||||
return false;
|
||||
);
|
||||
|
||||
boolean success = result != null && Integer.parseInt(result.toString()) == 1;
|
||||
System.out.println("【LUA绝杀锁】节点=" + System.identityHashCode(this)
|
||||
+ " 结果=" + success + " key=" + lockKey);
|
||||
return success;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user