Redis Lua同步锁实现源码解析

Ophelia ·
更新时间:2024-11-10
· 1716 次阅读

目录

Redis+Lua同步锁

Jedis配置

Jedis工具类→获取jedis

redis 锁工具类

加锁示例(jedis+lua)

Redis+Lua同步锁 Jedis配置 @Configuration @Getter @Setter @Slf4j @ConfigurationProperties(prefix = "jedis") public class JedisConfig { @Value("${spring.redis.host}") private String host; @Value("${spring.redis.port}") private int port; @Value("${spring.redis.password}") private String password; private int timeout; private int maxTotal; private int maxIdle; private int minIdle; @Bean public JedisPool jedisPool() { JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); jedisPoolConfig.setMaxIdle(maxIdle); jedisPoolConfig.setMinIdle(minIdle); jedisPoolConfig.setMaxTotal(maxTotal); JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout, password); log.info("JedisPool连接成功:" + host + "\t" + port); return jedisPool; } } Jedis工具类→获取jedis @Component public class JedisUtil { @Resource private JedisPool jedisPool; /** * 获取Jedis资源 */ public Jedis getJedis() { return jedisPool.getResource(); } /** * 释放Jedis连接 */ public void close(Jedis jedis) { if (jedis != null) { jedis.close(); } } } redis 锁工具类 public class RedisLockUtil { private static final Long RELEASE_SUCCESS = 1L; private static final String PREFIX = "API_LOCK_"; /** * 释放分布式锁 * * @param jedis * @param lockKey * @param valve * @return boolean * @author ll * @date 2023/02/09 14:31 */ public static boolean unLock(Jedis jedis, String lockKey, String valve) { String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end"; Object result = jedis.eval(script, Collections.singletonList(PREFIX + lockKey), Collections.singletonList(PREFIX + valve)); if (RELEASE_SUCCESS.equals(result)) { return true; } return false; } /** * 加分布式锁 * * @param jedis * @param lockKey * @param valve * @param timeout * @return boolean * @author ll * @date 2023/02/09 14:31 */ public static boolean lock(Jedis jedis, String lockKey, String valve, int timeout) { String script = "if redis.call('setnx',KEYS[1],ARGV[1]) == 1 then" + " redis.call('expire',KEYS[1],ARGV[2]) return 1 else return 0 end"; Object result = jedis.eval(script, Collections.singletonList(PREFIX + lockKey), Lists.newArrayList(PREFIX + valve, String.valueOf(timeout))); //判断是否成功 if (RELEASE_SUCCESS.equals(result)) { return true; } return false; } } 加锁示例(jedis+lua) @Slf4j @Component public class InterfaceEventListener { @Resource private JedisUtil jedisUtil; @Value("${jedis.lock.cycle-number}") private int cycleNumber; @Value("${jedis.lock.expire-time}") private int expireTime; @Value("${jedis.lock.sleep-time}") private int sleepTime; @Value("${spring.redis.database}") private int database; public void onApplicationEvent(InterfaceEvent event) { Jedis jedis = jedisUtil.getJedis(); jedis.select(database); boolean unLock = false; boolean lock; int currentNumber = 0; try { do { lock = RedisLockUtil.lock(jedis, "lockKey", "valve", expireTime); if (lock) { try { //todo 加锁的代码 } catch (Exception e) { log.error(e.getMessage()); e.printStackTrace(); } finally { unLock = RedisLockUtil.unLock(jedis, detectCode, detectCode); } } currentNumber++; Thread.sleep(sleepTime); } while (!unLock && currentNumber < cycleNumber); } catch (Exception e) { e.printStackTrace(); log.error(e.getMessage()); } finally { jedisUtil.close(jedis); } } }

以上就是Redis Lua同步锁实现源码解析的详细内容,更多关于Redis Lua同步锁的资料请关注软件开发网其它相关文章!



Lua 源码 Redis

需要 登录 后方可回复, 如果你还没有账号请 注册新账号