1 Star 0 Fork 0

CaptialSTeam/ubdframe

加入 Gitee
与超过 1400万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
redis.go 1.65 KB
一键复制 编辑 原始数据 按行查看 历史
sage 提交于 2024-12-17 18:17 +08:00 . add admin app
package lockers
import (
"fmt"
"github.com/go-redis/redis/v7"
"os"
"time"
)
// RedisDisLocker 基于redis的分布式锁
type RedisDisLocker struct {
rds *redis.Client
lockValue string
}
func NewRedisDisLocker(rds *redis.Client) (*RedisDisLocker, error) {
name, err := os.Hostname()
if err != nil {
name = fmt.Sprintf("unknow_%d", time.Now().UnixNano())
}
return &RedisDisLocker{
rds: rds,
lockValue: "locked_on_" + name,
}, nil
}
// Lock 尝试加锁 ttl: 秒级
func (l *RedisDisLocker) Lock(key string, ttl int64) (bool, error) {
_, err := l.rds.Do("set", key, l.lockValue, "NX", "EX", ttl).Result()
if err == redis.Nil {
return false, nil
} else if err != nil {
return false, err
}
return true, nil
}
// Release 释放锁
func (l *RedisDisLocker) Release(key string) error {
luaDelete := redis.NewScript(`if redis.call("get", KEYS[1]) == ARGV[1] then return redis.call("del", KEYS[1]) else return 0 end`)
_, err := luaDelete.Run(l.rds, []string{key}, l.lockValue).Result()
return err
}
// Delay 延长锁 ttl: 秒级
func (l *RedisDisLocker) Delay(key string, ttl int64) error {
luaRefresh := redis.NewScript(`if redis.call("get", KEYS[1]) == ARGV[1] then return redis.call("pexpire", KEYS[1], ARGV[2]) else return 0 end`)
_, err := luaRefresh.Run(l.rds, []string{key}, l.lockValue, ttl*1000).Result()
return err
}
// TTL 返回锁剩余时间 毫秒级
func (l *RedisDisLocker) TTL(key string) (int64, error) {
luaPTTL := redis.NewScript(`if redis.call("get", KEYS[1]) == ARGV[1] then return redis.call("pttl", KEYS[1]) else return -3 end`)
t, err := luaPTTL.Run(l.rds, []string{key}, l.lockValue).Result()
return t.(int64), err
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/captials-team/ubdframe.git
git@gitee.com:captials-team/ubdframe.git
captials-team
ubdframe
ubdframe
v1.0.0

搜索帮助