登录
首页 >  Golang >  Go问答

Redis分布式锁不生效

来源:stackoverflow

时间:2024-04-19 08:36:32 432浏览 收藏

Golang小白一枚,正在不断学习积累知识,现将学习到的知识记录一下,也是将我的所得分享给大家!而今天这篇文章《Redis分布式锁不生效》带大家来了解一下##content_title##,希望对大家的知识积累有所帮助,从而弥补自己的不足,助力实战开发!


问题内容

我正在使用go-redis分布式锁实现互斥访问,我的服务器是单线程服务器。但同时,很多请求都获得了分布式锁

func (redismgrptr *redismgr) getlock(key string) (int32) {
    encodekey := transcoding.base64encode(key)
    _, err := redismgrptr.redisclient.setnx(redismgrptr.ctx, 
    encodekey, 1, timeout).result()
    if err != nil {
        return -1
    }
    return 0
}

func (redismgrptr *redismgr) dellock(key string, sessionid string) {
    encodekey := transcoding.base64encode(key)
    redismgrptr.redisclient.del(redismgrptr.ctx, encodekey)
    log.errorf("session[%s] del lock", sessionid)
}

获取锁码是这样的:

func (redismgrptr *redismgr) getserver(name string, session string) () {
    for { 
        locres := redismgrptr.getlock(name) 
        if locres == 0 {
            break
        } else {
            time.sleep(5 * time.millisecond)
            continue
        }
    }
    defer redismgrptr.dellock(scenelock, sessionid)
    log.errorf("session[%s] get lock", sessionid)
    // do something
}

我发现很多请求同时获得锁,结果是

2021-09-08T15:05:21.073+0800 session[51776955325] get lock
2021-09-08T15:05:21.073+0800 session[91776955325] get lock
2021-09-08T15:05:21.073+0800 session[71776955325] get lock

我认为同一时间只有一个会话可以获得锁


正确答案


问题似乎出在锁定功能上。它不检查该值是否存在,而只是检查错误。

func (redismgrptr *redismgr) getlock(key string) (int32) {
    encodekey := transcoding.base64encode(key)
    wasset, err := redismgrptr.redisclient.setnx(redismgrptr.ctx, encodekey, 1, timeout).result()
    if err != nil || !wasset {
        return -1
    }
    return 0
}

...或者使用布尔值来更容易推理:

func (redismgrptr *redismgr) getlock(key string) (ok bool) {
    encodekey := transcoding.base64encode(key)
    wasset, err := redismgrptr.redisclient.setnx(redismgrptr.ctx, encodekey, 1, timeout).result()
    return err == nil && wasset
}

使用布尔版本 getserver 可能如下所示:

func (redisMgrPtr *RedisMgr) GetServer(name string, session string) () {
    for { 
        if ok := redisMgrPtr.getLock(name); ok {
            break
        }
        time.Sleep(5 * time.Millisecond)
    }
    defer redisMgrPtr.delLock(sceneLock, sessionId)
    Log.Errorf("session[%s] get lock", sessionId)
    // do something
}

理论要掌握,实操不能落!以上关于《Redis分布式锁不生效》的详细介绍,大家都掌握了吧!如果想要继续提升自己的能力,那么就来关注golang学习网公众号吧!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>