久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

redis中的分布式鎖有哪些特點

183次閱讀
沒有評論

共計 2683 個字符,預計需要花費 7 分鐘才能閱讀完成。

本篇內容主要講解“redis 中的分布式鎖有哪些特點”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓丸趣 TV 小編來帶大家學習“redis 中的分布式鎖有哪些特點”吧!

分布式鎖的特點

1. 獨占性

不論在任何情況下都只能有一個線程持有鎖。

2. 高可用

redis 集群環境不能因為某一個節點宕機而出現獲取鎖或釋放鎖失敗。

3. 防死鎖

必須有超時控制機制或者撤銷操作。

4. 不亂搶

自己加鎖,自己釋放。不能釋放別人加的鎖。

5. 重入性

同一線程可以多次加鎖。

redis 單機怎么實現

一般情況下都是使用 setnx+lua 腳本實現。

直接貼代碼

package com.fandf.test.redis;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Collections;
import java.util.concurrent.TimeUnit;
 * redis  單機鎖
 *
 * @author fandongfeng
 * @date 2023/3/29 06:52
 */
@Slf4j
@Service
public class RedisLock {
 @Resource
 RedisTemplate String, Object  redisTemplate;
 private static final String SELL_LOCK =  kill: 
 /**
 *  模擬秒殺
 *
 * @return  是否成功
 */
 public String kill() {
 String productId =  123 
 String key = SELL_LOCK + productId;
 // 鎖 value, 解鎖時   用來判斷當前鎖是否是自己加的
 String value = IdUtil.fastSimpleUUID();
 // 加鎖   十秒鐘過期   防死鎖
 Boolean flag = redisTemplate.opsForValue().setIfAbsent(key, value, 10, TimeUnit.SECONDS);
 if (!flag) {
 return  加鎖失敗 
 }
 try {
 String productKey =  good123 
 // 獲取商品庫存
 Integer stock = (Integer) redisTemplate.opsForValue().get(productKey);
 if (stock == null) {
 // 模擬錄入數據,  實際應該加載時從數據庫讀取
 redisTemplate.opsForValue().set(productKey, 100);
 stock = 100;
 }
 if (stock  = 0) {
 return  賣完了,下次早點來吧 
 }
 // 扣減庫存,  模擬隨機賣出數量
 int randomInt = RandomUtil.randomInt(1, 10);
 redisTemplate.opsForValue().decrement(productKey, randomInt);
 //  修改 db, 可以丟到隊列里慢慢處理
 return  成功賣出  + randomInt +  個,庫存剩余  + redisTemplate.opsForValue().get(productKey) +  個 
 } finally {
// // 這種方法會存在刪除別人加的鎖的可能
// redisTemplate.delete(key);
// if(value.equals(redisTemplate.opsForValue().get(key))){
// // 因為 if 條件的判斷和  delete 不是原子性的,// //if 條件判斷成功后,恰好鎖到期自己解鎖
// // 此時別的線程如果持有鎖了,就會把別人的鎖刪除掉
// redisTemplate.delete(key);
// }
 // 使用 lua 腳本保證判斷和刪除的原子性
 String luaScript =
  if (redis.call( get ,KEYS[1]) == ARGV[1]) then   +
  return redis.call(del ,KEYS[1])   +
  else   +
  return 0   +
  end 
 redisTemplate.execute(new DefaultRedisScript (luaScript, Boolean.class), Collections.singletonList(key), value);
 }
 }

}

進行單元測試,模擬一百個線程同時進行秒殺

package com.fandf.test.redis;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.RepeatedTest;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.parallel.Execution;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
import static org.junit.jupiter.api.parallel.ExecutionMode.CONCURRENT;
 * @Description:
 * @author: fandongfeng
 * @date: 2023-3-24 16:45
 */
@SpringBootTest
class SignServiceTest {
 
 @Resource
 RedisLock redisLock;

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-07-13發表,共計2683字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 轮台县| 高清| 嵩明县| 儋州市| 尖扎县| 武宁县| 安仁县| 精河县| 无锡市| 赤壁市| 红桥区| 武清区| 洪江市| 昌黎县| 高台县| 论坛| 土默特左旗| 桃园县| 扬中市| 闽清县| 密山市| 红桥区| 台州市| 高雄县| 大竹县| 凌海市| 丹寨县| 汤阴县| 霸州市| 武汉市| 彰化县| 铜鼓县| 广汉市| 吐鲁番市| 秭归县| 阜城县| 吉隆县| 肇州县| 丰原市| 福安市| 竹北市|