大廠的Redis鎖竟然是這麼用的,難怪不會超賣!

2021-10-18 03:37:02 字數 2408 閱讀 2036

常用的即 synchronize 或 lock 等 jdk 自帶的鎖,只能鎖住當前程序,僅適用於單體架構服務。 而在分布式多服務例項場景下必須使用分布式鎖

2.1 分布式鎖的原理

廁所佔坑理論

可同時去乙個地方「佔坑」:

可通過自旋方式自旋

「佔坑」可以去redis、db、任何所有服務都能訪問的地方。

2.2 分布式鎖演進

一階段

// 佔分布式鎖,去redis佔坑

問題場景解決方案:設定鎖的自動過期,即使沒有刪除,會自動刪除。

階段二

// 1. 佔分布式鎖,去redis佔坑

boolean lock = redistemplate.

opsforvalue()

.setifabsent

("lock"

,"110")if

(lock)

else

問題場景

解決方案:設定過期時間和佔位必須是原子操作。redis支援使用setnxex命令

階段三

// 1. 分布式鎖佔坑

boolean lock = redistemplate.

opsforvalue()

.setifabsent

("lock"

,"110"

,300

, timeunit.

seconds);

if(lock)

(// 加鎖成功,執行業務

// 2. 設定過期時間,必須和加鎖一起作為原子性操作

// redistemplate. expire( "lock", з0, timeunit.seconds);

map> datafromdb =

getdatafromdb()

;// 刪除鎖

redistemplate.

delete

( key:

"lock"

)return datafromdb;

else

階段四已經拿到了 lockvalue ,有了 uuid,但是過期了現在!其他人拿到所鎖設定了新值,於是 if 後將別人的鎖刪了!!也就是刪除鎖不是原子操作。

map> datafromdb =

getdatafromdb()

;string lockvalue = redistemplate.

opsforvalue()

.get

("lock");

if(uuid.

equals

(lockvalue)

)

問題場景

刪除鎖必須保證原子性。使用redis+lua指令碼。

階段五

string script = 

"if redis.

call

('get'

,keys[1

])==ar**[1

] then return redis.

call

('del'

,keys[1

])else

return

0 end";

保證加鎖【佔位+過期時間】和刪除鎖【判斷+刪除】的原子性。 更難的事情,鎖的自動續期。

Object Pascal與C 竟然是相同的!

object pascal與c 的相同之處!竟然這麼相同,包括相似的程式結構 而且,object pascal的語法竟然比c 還嚴格 怪不得borland能把object pascal和c 能混用 我看到以前有人說要把delphi中的vcl用c來寫,其實根本沒這個必要,這個vcl很容易地就可以轉成用...

銷售的最高境界竟然是聊天

銷售 聊天。1 真正的銷售是乙個愉快的聊天過程 聊對方的心願 聊對方的擔憂 聊如何完成對方的心願 聊如何拿走對方的擔憂。2 真正的銷售沒有對立的立場,沒有買方沒有賣方。3 真正的銷售是全心地為對方解決問題。4 真正的銷售不需要說服對方。5 真正的銷售彼此沒有壓力。6 真正的銷售是我們說的是對方想聽的...

震驚 python中的異常竟然是這樣的

在我們日常的程式設計過程中,經常會出現報錯的情況,那鮮紅的顏色讓很多的程式猿心慌慌,寫碼一小時,找錯一整天,所以今天我們就來細緻的講解一下程式執行中的異常報錯,讓我們不在恐懼那小小的程式報錯 error 首先我們得知己知彼,才能百戰不殆 當程式在執行 現的錯誤,或邏輯語法出現問題,直譯器此時無法繼續...