redis 分布式锁
2021/7/4 19:24:34
本文主要是介绍redis 分布式锁,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
redis 实现加锁、解锁操作
- 前言
- 一、关键方法
- 二、代码实现
- 1.加锁
- 2.解锁
- 总结
前言
在高并发下,由多渠道发起的同一业务请求,如果后台保护不周,会出现同时生成多笔相同的数据,比如相同订单,相同业务请求,在生产系统中造成垃圾数据,甚至出现生产事故,在前端增加控制已不足已解决的情况下,通过redis加锁,实现同一笔请求当有效期内只有一笔数据,下面详细介绍代码实现。
一、关键方法
加锁-setnx、设置有效期-expire、获取值-get、解锁-del
二、代码实现
1.加锁
/** * @Title: getRedisLock * @Description: TODO 1、获取锁之前的超时时间---在尝试获取锁的时候,如果在规定的时间内还没有获取锁,直接放弃;2、获取锁之后的超时时间---当获取锁成功之后,对应key有有效期,在规定时间内进行失效 * @Description: TODO 基于redis实现分布式锁代码思路:获取锁、释放锁 * @param acquireTimeout 在获取锁之前的超时时间 * @param timeOut 在获取锁之后的超时时间 * @param ywqqid redis key对应的value值(ywqqid唯一)作用:加锁和释放锁 * @return: ywqqid */ public String getRedisLock(Long acquireTimeout, Long timeOut, String ywqqid) { JedisPool jedisPool = null; Jedis conn = null; try { //获取redis线程池 jedisPool = RedisConnPool.getPool(); //建立redis连接 conn = jedisPool.getResource(); //定义在获取锁之后的超时时间,以秒为单位 int expireLock = (int)(timeOut / 1000); //定义在获取锁之前的超时时间,使用循环机制,如果没有获取到锁,要在规定acquireTimeout时间,保证重复进行尝试获取锁 Long endTime = System.currentTimeMillis() + acquireTimeout; while (System.currentTimeMillis() < endTime) { //插入对应的redislockKey,如果返回为1则成功获取锁,如果有效期内再进行setnx,则加锁失败,返回0 if(conn.setnx(ywqqid, ywqqid) == 1) { //设置对应key的有效期,防止redis挂掉造成死锁 conn.expire(ywqqid, expireLock); //返回ywqqid代表,对唯一的一笔业务加锁成功,其他相同的请求不能再去执行 return ywqqid; } } } catch (Exception e) { e.printStackTrace(); } finally{ //释放redis资源 jedisPool.returnResource(conn); conn = null; } //返回为null说明没有获取到锁,禁止重复操作 return null; }
2.解锁
/** * @Title: unRedisLock * @Description: TODO 释放redis锁,唯一 ywqqid 为 redislockKey * @param redislockKey * @param redislockValue * @return * @return: boolean */ public boolean unRedisLock(String redislockKey, String redislockValue) { JedisPool jedisPool = null; Jedis conn = null; try { //获取redis线程池 jedisPool = RedisConnPool.getPool(); //建立redis连接 conn = jedisPool.getResource(); //判断获取锁的时候保证自己删除自己,del 返回0,1(释放成功) if(redislockValue.equals(conn.get(redislockKey))) { Long delKey = conn.del(redislockKey); if(delKey > 0) { return true; }else { return false; } } } catch (Exception e) { e.printStackTrace(); }finally { //释放redis资源 jedisPool.returnResource(conn); conn = null; } return false; }
注意:在高版本中 redis 关闭连接用 close() 方法。
总结
- 在服务端,将唯一业务流水号,作为 key 和 value,加锁,后面如果有相同的流水号,则直接return掉,业务执行完成后,记得释放锁,释放锁可以通过del key 或者给锁设置有效期,有效期根据实际业务执行情况定夺。
- 设置有效期expire,过期后,锁自动失效
- 释放锁,del(key),释放锁之后,立即失效,跟有效期无关了
这篇关于redis 分布式锁的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-05-31Tiny RDM:你的下一代Redis桌面GUI神器-icode9专业技术文章分享
- 2024-03-21redisinsight-v2
- 2024-02-26Typed property App\Api\Mapper\GamePropsConfigMapper::$apiRedis must not be accessed before initia-icode9专业技术文章分享
- 2024-02-21redisson getlock
- 2024-02-20redis config
- 2024-02-20redis leaderboard
- 2024-01-23缓存选型:Redis or MemCache
- 2024-01-22面试官:Redis持久化能关吗?怎么关?
- 2024-01-21Redis压测工具redis-benchmark-icode9专业技术文章分享
- 2024-01-19这才是你应该了解的Redis数据结构!