Redis實現(xiàn)分布式鎖

偽代碼如下:

//整體流程
public void acquireLockMethod(){
    Map<String,Object> lockMap = new HashMap<>();
    try{
        lockMap = acquireLock(lockKey,expire);
        if(lockMap!=null){
            todoBusiness();//獲得鎖著蛙,執(zhí)行業(yè)務(wù)邏輯方法
        }
    }catch(Exception e){
        throw e;
    }finally{
    releaseLock(lockKey,lockMap);
    }
}
//acquireLock()方法:
public Map<String,Object> acquireLock(String lock,long expired){
    Map<String,Object> map = new HashMap<>();
    long value = System.currentTimeMillis() + expired + 1;
    long acquired = jedis.setnx(lock, String.valueOf(value)); 
    if (acquired == 1)
        map.put("isSuccess",true);
        map.put("expireTimeStr":value);
        return map;
    else {
        long oldValue = Long.valueOf(jedis.get(lock));
        //如果其他資源之前獲得鎖已經(jīng)超時                              
        if (oldValue < System.currentTimeMillis()){
            String getValue = jedis.getSet(lock, String.valueOf(value)); 
            //上一個鎖超時后會有很多線程去爭奪鎖,所以只有拿到oldValue的線程才是獲得鎖的甸箱。
            if (Long.valueOf(getValue) == oldValue)
                map.put("isSuccess",true);
                map.put("expireTimeStr":value);
                return map;
            else
                return null;
            }    
        else return null ;
}
//解鎖
private void release(ShardedJedis jedis, String lockKey,Map<String,Object> lockMap) {
        if(CollectionUtils.isEmpty(lockMap)){
            return;
        }
        Boolean locked = (Boolean) lockMap.get("isSuccess");
        String lockExpiresStr = (String) lockMap.get("expireTimeStr");
        if (locked) {
            String oldValueStr = jedis.get(lockKey);
            if (oldValueStr != null) {
                // 競爭的 redis.getSet 導(dǎo)致其時間跟原有的由誤差,若誤差在 超時范圍內(nèi)挣输,說明仍舊是 原來的鎖
                Long diff =  Long.parseLong(lockExpiresStr) - Long.parseLong(oldValueStr);
                if (diff < expireMsecs) {
                    jedis.del(lockKey);
                } else {
                    // 這個進程的鎖超時了,被 新的進程鎖獲得替換了站楚。則不進行任何操作良蛮。打印日志蠢棱,方便后續(xù)跟進
                    log.error("the lockKey over time.lockKey:{}.expireMsecs:{},over time is", lockKey, expireMsecs, System.currentTimeMillis() - Long.valueOf(lockExpiresStr));
                }
            }
        }
    }

此分布式鎖:
利用redis本身的單線程特性袭灯,以及setNX和getSet方法的原子特性髓介,保證了多請求的加鎖的互斥性,最后只有一個請求獲得鎖病毡。
可以通過使用while循環(huán)實現(xiàn)阻塞特定時間的鎖烁落。
通過getSet方法,沒有使用expire方法,保證了此分布式鎖不會造成死鎖。

此分布式鎖依舊存在的問題:

  1. 如果業(yè)務(wù)邏輯執(zhí)行時間超時(鎖此時自動失效了)嗦董,此時業(yè)務(wù)邏輯的數(shù)據(jù)已經(jīng)不安全经窖。雖然在解鎖的時候,判斷了鎖的value值,做到了不會錯誤釋放鎖的情況窖壕,但是對超時業(yè)務(wù)邏輯只是做了日志記錄呕乎,不太靠譜。
  2. redis集群部署時,這樣的分布式鎖會存在什么問題嗎。這個沒有試驗過。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子假褪,更是在濱河造成了極大的恐慌冤寿,老刑警劉巖狠角,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件堂飞,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拇泣,“玉大人噪叙,你說我怎么就攤上這事∶瓜瑁” “怎么了睁蕾?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長债朵。 經(jīng)常有香客問我子眶,道長,這世上最難降的妖魔是什么序芦? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任臭杰,我火速辦了婚禮,結(jié)果婚禮上芝加,老公的妹妹穿的比我還像新娘硅卢。我一直安慰自己,他們只是感情好藏杖,可當我...
    茶點故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布将塑。 她就那樣靜靜地躺著,像睡著了一般蝌麸。 火紅的嫁衣襯著肌膚如雪点寥。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天来吩,我揣著相機與錄音敢辩,去河邊找鬼。 笑死弟疆,一個胖子當著我的面吹牛戚长,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播怠苔,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼同廉,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了柑司?” 一聲冷哼從身側(cè)響起迫肖,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎攒驰,沒想到半個月后蟆湖,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡玻粪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年隅津,在試婚紗的時候發(fā)現(xiàn)自己被綠了诬垂。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡饥瓷,死狀恐怖剥纷,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情呢铆,我是刑警寧澤晦鞋,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布心肪,位于F島的核電站床蜘,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏野建。R本人自食惡果不足惜娜谊,卻給世界環(huán)境...
    茶點故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一确买、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧纱皆,春花似錦湾趾、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至近迁,卻和暖如春艺普,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背鉴竭。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工歧譬, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人搏存。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓瑰步,卻偏偏與公主長得像,于是被迫代替她去往敵國和親璧眠。 傳聞我的和親對象是個殘疾皇子面氓,可洞房花燭夜當晚...
    茶點故事閱讀 43,527評論 2 349

推薦閱讀更多精彩內(nèi)容