锁的作用是:当多个线程竞争一个资源时,会出现资源被干掉或者资源重置为另一个值,这时锁的作用就出现了,锁住当前的资源,其他线程就不会修改此数据了。
使用redis锁的思想是:将资源作为一个独立标识,然后放在字符串里面,并且使用过期时间来声明锁:
也可以手动释放,才去循环设置超时时间
SetNX 这个命令就很好地作为资源声明,创建一个锁:
import (
"context"
"go-redis/client"
"time"
"github.com/go-redis/redis/v8"
"github.com/google/uuid"
)
var ctx = context.TODO()
func Lock(lockname string, locktime int64) string {
u, _ := uuid.NewUUID()
ustr := u.String()
end := time.Now().Unix() + locktime
for {
if time.Now().Unix() < end {
client.RedisClient().SetNX(ctx, "lock:"+lockname, ustr, time.Hour)
return ustr
}
}
}
而释放锁,一般是两步合并的操作,因为它会减少IO操作。
两步分为:
获取资源
如果有此资源,释放锁(删除资源uuid)
package redislock
import (
"context"
"go-redis/client"
"time"
"github.com/go-redis/redis/v8"
"github.com/google/uuid"
)
var ctx = context.TODO()
// 释放锁
func Release(lockname string, indetifier string) bool {
pipline := client.RedisClient().TxPipeline()
lockname = "lock:" + lockname
for {
pipline.Get(ctx, lockname).Val()
cmders, _ := pipline.Exec(ctx)
perm, _ := cmders[0].(*redis.StringCmd).Result()
if perm == indetifier {
pipline.Del(ctx, lockname) // 删除锁
pipline.Exec(ctx)
return true
}
}
}
网友评论