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

GO 实现REDIS分布式原子锁的功能,第1张

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上面提供的驱动。如果你用其它的可以改一下就可以使用了

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/995711.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存