redis實現(xiàn)簡單分布式鎖
更新時間:2024年07月01日 11:46:44 作者:呱呱123#
這篇文章主要介紹了redis實現(xiàn)簡單分布式鎖,文中通過代碼示例講解的非常詳細,需要的朋友可以參考下
1.redisTemplate實現(xiàn)簡單分布式鎖
@Autowired RedisTemplate redisTemplate; /** * redis分布式鎖演示案例,此處使用redisTemplate * @param stockId 此處以扣減庫存為例子,stockId代表要扣減庫存的商品id,庫存數(shù)據(jù)是提前存在redis的,并和數(shù)據(jù)庫進行同步 * @return */ public AjaxResult redisLockDemo(String stockId){ //鎖前綴 final String stock_lock = "stock_lock:"; // 生成一個隨機唯一的值用于辨別鎖的使用對象 String clientId = UUID.randomUUID().toString(); //此處使用set(k,v,time,unit)來獲取鎖,確保加鎖和設(shè)置超時時間是原子操作 Boolean lock = redisTemplate.opsForValue().setIfAbsent(stock_lock + stockId, clientId, 10, TimeUnit.MILLISECONDS); if (!lock){ //獲取鎖失敗 return AjaxResult.error("服務(wù)器繁忙,請稍后再試!"); } //獲取鎖成功 //執(zhí)行扣減庫存 try { int stock = (int) redisTemplate.opsForValue().get(stockId); if (stock > 0){ int realStock = stock - 1; // 重新設(shè)置庫存數(shù)據(jù) redisTemplate.opsForValue().set(stockId, realStock + ""); // .............其他步驟 log.info("庫存扣減成功{}", stockId); } else { return AjaxResult.error("商品已經(jīng)被搶光了!"); } } finally { //釋放鎖 // if (clientId.equals(stringRedisTemplate.opsForValue().get(stock_lock + stockId))){ // stringRedisTemplate.delete(stock_lock + stockId); // } //此處使用lua腳本釋放鎖,具有原子性 String script = "local lockKey = KEYS[1]\n" + "local clientId = ARGV[1]\n" + "local currentHolder = redis.call('GET', lockKey)\n" + "if currentHolder == clientId then\n" + " redis.call('DEL', lockKey)\n" + " return true\n" + "else\n" + " return false\n" + "end"; DefaultRedisScript<Boolean> redisScript = new DefaultRedisScript<>(script, Boolean.class); Boolean result = (Boolean) redisTemplate.execute(redisScript, Collections.singletonList(stock_lock + stockId), clientId); if (result != null && result) { log.info("所釋放成功"); } else { log.info("所釋放失敗"); } } return AjaxResult.success("扣減庫存成功!"); }
2.redission實現(xiàn)分布式鎖
@Autowired Redisson redisson; /** * redis分布式鎖演示案例,redisson * @param stockId 此處以扣減庫存為例子,stockId代表要扣減庫存的商品id,庫存數(shù)據(jù)是提前存在redis的,并和數(shù)據(jù)庫進行同步 * @return */ public AjaxResult redissonLockDemo(String stockId){ final String lockKey = "stock_lock:"; RLock lock = redisson.getLock(lockKey); lock.lock(); try { //執(zhí)行扣減庫存 int stock = (int) redisTemplate.opsForValue().get(stockId); if (stock > 0){ int realStock = stock - 1; // 重新設(shè)置庫存數(shù)據(jù) redisTemplate.opsForValue().set(stockId, realStock + ""); // .............其他步驟 log.info("庫存扣減成功{}", stockId); } else { return AjaxResult.error("商品已經(jīng)被搶光了!"); } }finally { lock.unlock(); } return AjaxResult.success("扣減庫存成功!"); }
以上就是redis實現(xiàn)簡單分布式鎖的詳細內(nèi)容,更多關(guān)于redis分布式鎖的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
websocket+redis動態(tài)訂閱和動態(tài)取消訂閱的實現(xiàn)示例
本文主要介紹了websocket+redis動態(tài)訂閱和動態(tài)取消訂閱,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05通俗易懂的Redis數(shù)據(jù)結(jié)構(gòu)基礎(chǔ)教程(入門)
這篇文章主要介紹了通俗易懂的Redis數(shù)據(jù)結(jié)構(gòu)基礎(chǔ)教程,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03Redis?存儲對象信息用?Hash?和String的區(qū)別
這篇文章主要介紹了Redis存儲對象信息用Hash和String的區(qū)別,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下2022-09-09Redisson實現(xiàn)分布式鎖、鎖續(xù)約的案例
這篇文章主要介紹了Redisson如何實現(xiàn)分布式鎖、鎖續(xù)約,本文通過示例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-03-03Linux安裝Redis、后臺運行、系統(tǒng)自啟動的設(shè)置方法
Redis是用C語言編寫的開源免費的高性能的分布式內(nèi)存數(shù)據(jù)庫,基于內(nèi)存運行并支持持久化的NoSQL數(shù)據(jù)庫。這篇文章主要介紹了Linux安裝Redis、后臺運行、系統(tǒng)自啟動,需要的朋友可以參考下2020-01-01