redis實(shí)現(xiàn)簡(jiǎn)單分布式鎖
更新時(shí)間:2024年07月01日 11:46:44 作者:呱呱123#
這篇文章主要介紹了redis實(shí)現(xiàn)簡(jiǎn)單分布式鎖,文中通過(guò)代碼示例講解的非常詳細(xì),需要的朋友可以參考下
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)來(lái)獲取鎖,確保加鎖和設(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)文章
redis輕松處理經(jīng)緯度坐標(biāo)點(diǎn)數(shù)據(jù)的實(shí)現(xiàn)方法
這篇文章主要介紹了redis輕松處理經(jīng)緯度坐標(biāo)點(diǎn)數(shù)據(jù)的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10
詳解Centos7下配置Redis并開(kāi)機(jī)自啟動(dòng)
本篇文章主要介紹了Centos7下配置Redis并開(kāi)機(jī)自啟動(dòng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2016-11-11
5分鐘教你docker安裝啟動(dòng)redis全教程(全新方式)
今天,我來(lái)帶大家使用一種全新的方式docker來(lái)安裝redis,首先我們來(lái)了解一下什么是redis以及我們?yōu)槭裁匆褂胷edis,以及它的優(yōu)缺點(diǎn),感興趣的朋友跟隨小編一起學(xué)習(xí)下吧2021-05-05
Redis遠(yuǎn)程字典服務(wù)器?hash類型示例詳解
這篇文章主要介紹了Redis遠(yuǎn)程字典服務(wù)器?hash類型示例詳解,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-08-08

