栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Go语言

GO 实现REDIS分布式原子锁的功能

Go语言 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

GO 实现REDIS分布式原子锁的功能

package redis

import (
	"errors"
	"fmt"

	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/util/gconv"
	"github.com/gomodule/redigo/redis"
)

const (
	lockScript   = `return redis.call('SET', KEYS[1], ARGV[1], 'NX', 'EX', ARGV[2])`
	unlockScript = `
		if redis.call("get",KEYS[1]) == ARGV[1] then
		    return redis.call("del",KEYS[1])
		else
		    return 0
		end
	`
)

func Lock(key, value string, timeoutMs int) (bool, error) {
	r := g.Redis().Conn()
	defer r.Close()
	cmd := redis.NewScript(1, lockScript)
	if res, err := cmd.Do(r, key, value, timeoutMs); err != nil {
		//fmt.Printf("加锁失败, k:%v v:%v", key, value)
		return false, err
	} else {
		//fmt.Printf("加锁成功, k:%v v:%v res %v n", key, value, res)
		return gconv.String(res) == "OK", nil
	}
}

func Unlock(key, value string) error {
	r := g.Redis().Conn()
	defer r.Close()
	cmd := redis.NewScript(1, unlockScript)
	if res, err := redis.Int(cmd.Do(r, key, value)); err != nil {
		return err
	} else if res != 1 {
		msg := fmt.Sprintf("解锁失败, key:%v 或者 v:%v 错误", key, value)
		return errors.New(msg)
	}
	return nil
}

由于我当时用的是GF的框架所以REDIS也是用了GF上面提供的驱动。如果你用其它的可以改一下就可以使用了

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/908694.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号