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