12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970 |
- package dao
- import (
- "context"
- "math/rand"
- "time"
- "go-common/library/cache/redis"
- "go-common/library/log"
- )
- func randomString(l int) string {
- str := "0123456789abcdefghijklmnopqrstuvwxyz"
- bytes := []byte(str)
- result := []byte{}
- r := rand.New(rand.NewSource(time.Now().UnixNano()))
- for i := 0; i < l; i++ {
- result = append(result, bytes[r.Intn(len(bytes))])
- }
- return string(result)
- }
- // Lock .
- func (d *Dao) Lock(ctx context.Context, realKey string, ttl int, retry int, retryDelay int) (gotLock bool, lockValue string, err error) {
- if retry <= 0 {
- retry = 1
- }
- lockValue = "locked:" + randomString(5)
- retryTimes := 0
- conn := d.redis.Get(ctx)
- defer conn.Close()
- for ; retryTimes < retry; retryTimes++ {
- var res interface{}
- res, err = conn.Do("SET", realKey, lockValue, "PX", ttl, "NX")
- if err != nil {
- log.Error("redis_lock failed:%s:%s", realKey, err.Error())
- break
- }
- if res != nil {
- gotLock = true
- break
- }
- time.Sleep(time.Duration(retryDelay * 1000))
- }
- return
- }
- // UnLock .
- func (d *Dao) UnLock(ctx context.Context, realKey string, lockValue string) (err error) {
- conn := d.redis.Get(ctx)
- defer conn.Close()
- res, err := redis.String(conn.Do("GET", realKey))
- if err != nil {
- log.Error("redis_unlock get error:%s:%v", realKey, err)
- return
- }
- if res != lockValue {
- err = ErrUnLockGet
- return
- }
- _, err = conn.Do("DEL", realKey)
- if err != nil {
- log.Error("redis_unlock del error:%s:%v", realKey, err)
- }
- return
- }
|