1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
|
@Component public class RedisLockerUtil { private static final RedisScript<Boolean> LOCK_SCRIPT; private static final RedisScript<Boolean> UN_LOCK_SCRIPT;
static { String sb = "if (redis.call('setnx', KEYS[1], ARGV[1]) == 1) then return redis.call('expire', KEYS[1], tonumber(ARGV[2])) == 1 else return false end"; LOCK_SCRIPT = new DefaultRedisScript<>(sb, Boolean.class); }
static { String sb = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) == 1 else return false end"; UN_LOCK_SCRIPT = new DefaultRedisScript<>(sb, Boolean.class); }
@Autowired private RedisTemplate<Object, Object> redisTemplate;
public boolean tryLock(String key, String sessionId) { return tryLock(key, sessionId, 60, 10, 1000); }
public boolean tryLock(String key, String sessionId, long expireSeconds, int retryTimes, int sleepMills) { if (StringUtils.isBlank(key)) throw new IllegalArgumentException("key不能为空"); if (StringUtils.isBlank(sessionId)) throw new IllegalArgumentException("sessionId不能为空");
boolean lock = doLock(key, sessionId, expireSeconds); while (!lock && retryTimes > 0) { try { Thread.sleep(sleepMills); } catch (InterruptedException e) { e.printStackTrace(); } lock = doLock(key, sessionId, expireSeconds); retryTimes--; } return lock; }
public boolean releaseLock(String key, String sessionId) { Object object = redisTemplate.execute(UN_LOCK_SCRIPT, Collections.singletonList(key), sessionId); return (Boolean) object; }
private Boolean doLock(String key, String sessionId, long expireSeconds) { Object object = redisTemplate.execute(LOCK_SCRIPT, Collections.singletonList(key), sessionId, expireSeconds); return (Boolean) object; }
}
|