package redisdao import ( "context" "time" "git.lzcwy.cn/zhengchiliu/zt-closet-backend/global" "github.com/redis/go-redis/v9" ) // unlockScript 仅当锁值匹配时才删除,防止误删其他持有者的锁 var unlockScript = redis.NewScript(` if redis.call('GET', KEYS[1]) == ARGV[1] then return redis.call('DEL', KEYS[1]) else return 0 end `) // TryLock 尝试获取分布式锁(SET NX EX),获取成功返回 true。 // value 建议传唯一标识(如 request_id / uuid),用于释放时校验持有者。 func TryLock(ctx context.Context, key, value string, ttl time.Duration) (bool, error) { ctx, span := global.Tracer.Start(ctx, "redisdao.TryLock") defer span.End() ok, err := global.RedisEngine.SetNX(ctx, key, value, ttl).Result() if err != nil { span.RecordError(err) return false, err } return ok, nil } // Unlock 释放分布式锁,仅当 value 匹配时才删除;锁不存在或不属于自己时静默返回。 func Unlock(ctx context.Context, key, value string) error { ctx, span := global.Tracer.Start(ctx, "redisdao.Unlock") defer span.End() if err := unlockScript.Run(ctx, global.RedisEngine, []string{key}, value).Err(); err != nil { span.RecordError(err) return err } return nil }