diff --git a/redis/redis.go b/redis/redis.go index 12d92b6..b7297dd 100644 --- a/redis/redis.go +++ b/redis/redis.go @@ -4,6 +4,7 @@ import ( "context" "strings" "sync" + "time" "github.com/gogf/gf/v2/database/gredis" "github.com/gogf/gf/v2/frame/g" @@ -31,6 +32,36 @@ func GetRedisClient() *gredis.Redis { return getClient() } +// Lock 分布式锁 +func Lock(ctx context.Context, key string, expireSeconds int64, fn func(ctx context.Context)) { + limit := 3 +LOOP: + if limit < 0 { + return + } + limit-- + if val, err := RedisClient.Set(ctx, key, true, gredis.SetOption{ + TTLOption: gredis.TTLOption{ + EX: &expireSeconds, + }, + NX: true, + }); err != nil { + glog.Errorf(ctx, "RedisClient.Lock error: %v", err) + } else { + if val.Bool() { + defer func(RedisClient *gredis.Redis, ctx context.Context, key string) { + if _, err = RedisClient.Del(ctx, key); err != nil { + glog.Errorf(ctx, "RedisClient.Del error: %v", err) + } + }(RedisClient, ctx, key) + fn(ctx) + } else { + time.Sleep(time.Second) + goto LOOP + } + } +} + // RedisClient 导出的 Redis 客户端(供 mongo.go 使用,兼容旧代码) var RedisClient = getClient()