redis 實(shí)現(xiàn)并發(fā)鎖go

鎖的作用是:當(dāng)多個(gè)線程競(jìng)爭(zhēng)一個(gè)資源時(shí),會(huì)出現(xiàn)資源被干掉或者資源重置為另一個(gè)值,這時(shí)鎖的作用就出現(xiàn)了,鎖住當(dāng)前的資源,其他線程就不會(huì)修改此數(shù)據(jù)了。


使用redis鎖的思想是:將資源作為一個(gè)獨(dú)立標(biāo)識(shí),然后放在字符串里面,并且使用過(guò)期時(shí)間來(lái)聲明鎖:

也可以手動(dòng)釋放,才去循環(huán)設(shè)置超時(shí)時(shí)間


SetNX 這個(gè)命令就很好地作為資源聲明,創(chuàng)建一個(gè)鎖:


import (

"context"

"go-redis/client"

"time"


"github.com/go-redis/redis/v8"

"github.com/google/uuid"

)


var ctx = context.TODO()


func Lock(lockname string, locktime int64) string {

u, _ := uuid.NewUUID()

ustr := u.String()

end := time.Now().Unix() + locktime

for {

? if time.Now().Unix() < end {

? client.RedisClient().SetNX(ctx, "lock:"+lockname, ustr, time.Hour)

? return ustr

? }

}

}

而釋放鎖,一般是兩步合并的操作,因?yàn)樗鼤?huì)減少IO操作。


兩步分為:


獲取資源

如果有此資源,釋放鎖(刪除資源uuid)

package redislock


import (

"context"

"go-redis/client"

"time"


"github.com/go-redis/redis/v8"

"github.com/google/uuid"

)


var ctx = context.TODO()


// 釋放鎖

func Release(lockname string, indetifier string) bool {

pipline := client.RedisClient().TxPipeline()

lockname = "lock:" + lockname

for {

? pipline.Get(ctx, lockname).Val()

? cmders, _ := pipline.Exec(ctx)

? perm, _ := cmders[0].(*redis.StringCmd).Result()

? if perm == indetifier {

? pipline.Del(ctx, lockname) // 刪除鎖

? pipline.Exec(ctx)

? return true

? }

}

}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容