記錄一次redis分佈式鎖的坑

redis分佈式鎖的實現方式是:

lock(){
    sync(this){
//無法獲取自旋 setnx(key,UUID) setex(60s)
return UUID } } unlock(key,value){ sync(this){ if(get(key) == UUID){ del(key) } } }

備註:由於redisTemplate版本問題,沒有setnxex的原子操作,而且unlock也有兩步操作,爲了保證單機原子性,加上了sync對象鎖,並且lock和unlock鎖同一個對象。

看山去一切都很美,但是運行起來發現問題了:併發量一上來,分佈式鎖並不會正常解鎖,而是每次都要等60s自動過期後才能解鎖。。。。

仔細分析了下問題原因:

線程A先進入lock方法,獲取sync對象鎖,獲取到分佈式鎖,釋放sync對象鎖

線程A執行業務代碼

線程B進入lock方法,獲取sync對象鎖,但無法獲取分佈式鎖,自旋等待

線程A進入unlock方法,嘗試獲取sync對象鎖,但此時sync對象鎖被線程B佔用,需要等待線程B釋放sync對象鎖

這時線程A B有死鎖,需要等待其中一個鎖自動解鎖,就是分佈式鎖的60s,這就解釋了爲什麼每次都要等60s!!!!

而且這種方法還只能在單機保證線程安全,想要實現一個優秀的分佈式鎖,還必須要滿足分佈式原子性!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章