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)來獲取鎖,確保加鎖和設置超時時間是原子操作
Boolean lock = redisTemplate.opsForValue().setIfAbsent(stock_lock + stockId, clientId, 10, TimeUnit.MILLISECONDS);
if (!lock){
//獲取鎖失敗
return AjaxResult.error("服務器繁忙,請稍后再試!");
}
//獲取鎖成功
//執(zhí)行扣減庫存
try {
int stock = (int) redisTemplate.opsForValue().get(stockId);
if (stock > 0){
int realStock = stock - 1;
// 重新設置庫存數(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ù)據(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)容,更多關于redis分布式鎖的資料請關注腳本之家其它相關文章!
相關文章
redis輕松處理經(jīng)緯度坐標點數(shù)據(jù)的實現(xiàn)方法
這篇文章主要介紹了redis輕松處理經(jīng)緯度坐標點數(shù)據(jù)的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-10-10

