分布式redis锁实现:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.stereotype.Component;
import java.util.Collections;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
/**
* redis锁工具类
*
* @Author YL
* @Create 2022/8/11 21:55
* @Version 1.0
*/
@Component
public class RedisLockUtil {
public static final String redisLockKeyPrefix = "redisLockPrefix:";
@Autowired
private StringRedisTemplate redisTemplate;
/**
* 尝试获取redis锁
*
* @param businessKey 业务key
* @param lockTime 加锁时长,单位毫秒
* @param tryMaxCount 最大重试次数
* @return
*/
public String tryGetLock(String businessKey, long lockTime, int tryMaxCount) {
String redisKey = redisLockKeyPrefix + businessKey;
String lockVal = UUID.randomUUID().toString();
Boolean lockResult;
do {
lockResult = redisTemplate.opsForValue().setIfAbsent(redisKey, lockVal, lockTime, TimeUnit.MILLISECONDS);
try {
TimeUnit.MILLISECONDS.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
} while (!lockResult && --tryMaxCount > 0);
return lockResult ? lockVal : null;
}
/**
* 释放锁
*
* @param businessKey 业务key
* @param lockVal 锁val
* @return
*/
public boolean releaseLock(String businessKey, String lockVal) {
String redisKey = redisLockKeyPrefix + businessKey;
RedisScript<Long> script = RedisScript.of("if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end", Long.class);
Long delNum = redisTemplate.execute(script, Collections.singletonList(redisKey), lockVal);
return delNum >= 1;
}
}