十步學習 Redis 分布式鎖

2021-10-16 12:36:02 字數 4407 閱讀 8681

/**

* @author mr.superbeyone

**/public

class

redislocktest

}}

問題:出現超賣現象

/**

* @author mr.superbeyone

**/public

class

redislocktest}}

/** * lock 過期不候

*/public

void

test3()

throws interruptedexception

}finally

}else

}}

問題:分布式部署後,單機鎖還是會出現超賣現象,需要分布式鎖

public

class

redislocktest

string key =

"key"

; string countval = stringredistemplate.

opsforvalue()

.get

(key)

;int count = countval == null ?

0: integer.

parseint

(countval);if

(count >0)

}}

問題 :有可能不能釋放鎖

public

class

redislocktest

string key =

"key"

; string countval = stringredistemplate.

opsforvalue()

.get

(key)

;int count = countval == null ?

0: integer.

parseint

(countval);if

(count >0)

}finally

}}

問題:機器宕機,不能保證最後的解鎖

public

class

redislocktest

string key =

"key"

; string countval = stringredistemplate.

opsforvalue()

.get

(key)

;int count = countval == null ?

0: integer.

parseint

(countval);if

(count >0)

}finally

}}

問題:加鎖和設定過期時間 沒***原子性

public

class

redislocktest

string key =

"key"

; string countval = stringredistemplate.

opsforvalue()

.get

(key)

;int count = countval == null ?

0: integer.

parseint

(countval);if

(count >0)

}finally

}}

問題:處理業務的時間大於設定的鎖過期時間,執行緒b可能執行緒a的鎖,刪除別人的鎖

public

class

redislocktest

string key =

"key"

; string countval = stringredistemplate.

opsforvalue()

.get

(key)

;int count = countval == null ?

0: integer.

parseint

(countval);if

(count >0)

}finally}}

}

問題:刪除自己的鎖判斷 與 刪除操作 不是原子性 ,可能判斷加鎖與解鎖的不是同乙個客戶端,有可能會出現誤解鎖

可以使用 lua 指令碼 解決

if redis.

call

("get"

,keys[1]

)== ar**[1]

then

return redis.

call

("del"

,keys[1]

)else

return

0end

public

class

redislocktest

string key =

"key"

; string countval = stringredistemplate.

opsforvalue()

.get

(key)

;int count = countval == null ?

0: integer.

parseint

(countval);if

(count >0)

}finally

} stringredistemplate.

unwatch()

;//刪除鎖成功

break;}

}}}

問題:確保 redis 過期時間大於業務執行時間的問題,redis 分布式鎖如何續期?

public

class

redislocktest

string key =

"key"

; string countval = stringredistemplate.

opsforvalue()

.get

(key)

;int count = countval == null ?

0: integer.

parseint

(countval);if

(count >0)

}finally

else

}finally}}

}}

問題:確保 redis 過期時間大於業務執行時間的問題,redis 分布式鎖如何續期?

>

>

org.redissongroupid

>

>

redissonartifactid

>

>

3.14.1version

>

dependency

>

public

class

redisconfig

}

public

class

redislocktest

}finally

}}

問題:超高併發情況下,可能出現 illegalmonitorstateexception: attempt to unlock, no locked by current thread by node id …

/**

* 引入 redis 分布式鎖

* 加鎖 解鎖,lock/unlock 必須同時出現並保證呼叫

* 鎖 自動刪除 原子性操作

* 刪除自己的鎖

* redisson

*/public

void

test12()

}finally

}}

mr.superbeyone

redis分布式鎖

redis分布式鎖 直接上 我寫了四個redis分布式鎖的方法,大家可以提個意見 第一種方法 redis分布式鎖 param timeout public void lock long timeout thread.sleep 100 catch exception e override publi...

Redis分布式鎖

分布式鎖一般有三種實現方式 1.資料庫樂觀鎖 2.基於redis的分布式鎖 3.基於zookeeper的分布式鎖.首先,為了確保分布式鎖可用,我們至少要確保鎖的實現同時滿足以下四個條件 互斥性。在任意時刻,只有乙個客戶端能持有鎖。不會發生死鎖。即使有乙個客戶端在持有鎖的期間崩潰而沒有主動解鎖,也能保...

redis分布式鎖

使用redis的setnx命令實現分布式鎖 redis為單程序單執行緒模式,採用佇列模式將併發訪問變成序列訪問,且多個客戶端對redis的連線並不存在競爭關係。redis的setnx命令可以方便的實現分布式鎖。setnx key value 將key的值設為value,當且僅當key不存在。如給定的...