package com.chinaztt.mes.warehouse.util; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisCallback; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import java.util.Objects; /** * @Author: Zero * @Date: 2022/9/16 14:43 * @Description: */ @Component public class RedisLockHelper { @Autowired private RedisTemplate redisTemplate; public static final String LOCK_PREFIX = "redis_reverse_lock"; public static final int LOCK_EXPIRE = 5000; public Boolean lock(String key) { String lock = LOCK_PREFIX + key; return (Boolean) redisTemplate.execute((RedisCallback) connection -> { long expireAt = System.currentTimeMillis() + LOCK_EXPIRE + 1; Boolean acquire = connection.setNX(lock.getBytes(), String.valueOf(expireAt).getBytes()); if (acquire) { return Boolean.TRUE; } else { byte[] value = connection.get(lock.getBytes()); if (Objects.nonNull(value) && value.length > 0) { long expireTime = Long.parseLong(new String(value)); // 如果锁已经过期 if (expireTime < System.currentTimeMillis()) { // 重新加锁,防止死锁 byte[] oldValue = connection.getSet(lock.getBytes(), String.valueOf(System.currentTimeMillis() + LOCK_EXPIRE + 1).getBytes()); return Long.parseLong(new String(oldValue)) < System.currentTimeMillis(); } } } return Boolean.FALSE; }); } public void delLock(String key) { redisTemplate.execute((RedisCallback) redisConnection -> { redisConnection.del((LOCK_PREFIX + key).getBytes()); return null; }); } }