package utils import ( "context" "adm-ads/common.in/cache" "fmt" "time" ) type Lock struct { Key string Ttl int64 cancel context.CancelFunc } // 监听过期 func (lock *Lock) WatchLock(ctx context.Context) { sleepTime := time.Duration(lock.Ttl * 2 / 3) t1 := time.Tick(sleepTime * time.Second) for { select { case <-t1: cache.Redis.Expire(lock.Key, lock.Ttl) case <-ctx.Done(): return } } } // 停止监听 func (lock *Lock) StopWatch() { lock.cancel() } // 加分布式锁 func (lock *Lock) RedisLock() (bool,error) { if lock.Key == "" || lock.Ttl <= 0 { return false,fmt.Errorf("参数错误") } res, err := cache.Redis.SetNxEx(lock.Key, "lock", lock.Ttl) // redis 操作失败 if err != nil { return false,err } // 上锁成功 if res { ctx, cancel := context.WithCancel(context.Background()) lock.cancel = cancel go lock.WatchLock(ctx) return true,nil } return false,nil } func (lock *Lock) TryRedisLock() error { for{ islock ,err := lock.RedisLock() if err != nil{ return err }else{ if islock{ return nil }else{ time.Sleep(1*time.Second) } } } } // 释放分布式锁 func (lock *Lock) RedisUnlock() { // 停止监听 lock.StopWatch() // 删除分布式锁 cache.Redis.Del(lock.Key) }