修改多节点同时执行任务情况

This commit is contained in:
sh
2026-04-02 17:15:02 +08:00
parent ebd681e99b
commit 10a28b1b0b

View File

@@ -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;
}