欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

最近开发用到的分布式锁

程序员文章站 2022-06-02 08:18:23
...

最近开发的场景有分布式任务,任务是创建某些资源,只有创建成功了,某些资源才可使用。此时要考虑用分布式锁,有以下几种思路

1.通过数据库,其实是创建一张表,字段类似于,id,key,values,status(和values字段二选一),createTime。要锁定某个对象时,以其唯一性的字段(例如id)作为key,数据作为values存入,此时为锁定状态;解锁时,将values致为null。写个定时任务,查询createTime,使超时的锁失效。但是这个情况,需要数据库具有强一致性,不能多人同时对一个数据做操作,而且数据库和代码程序是两套程序,不好维护

2.通过程序(代码)

1> 创建一个map,让map充当表的作用,在这个项目存活期间,一直有效,当操作某个对象时,将这个对象,以kv形式放入map,而且要保证map是唯一一个,此时就用到了单例模式;而且map的set和put是只能同时一人操作的,故要加锁。代码如下:

var InstanceMap map[string]interface{}

func GetInstanceMap()map[string]interface{}{
   var rw sync.Mutex
   rw.Lock()
   defer rw.Unlock()
   if nil == InstanceMap{
      InstanceMap = make(map[string]interface{})
   }
   return InstanceMap
}

func LockInstanceMap(k string,v interface{})error{
   var rw sync.Mutex
   rw.Lock()
   defer rw.Unlock()
   InstanceMap = GetInstanceMap()
   if InstanceMap[k] == nil{
      InstanceMap[k] = v
      return nil
   }else{
      beego.Error("该 k = " + k + " 存在 v = ",v)
      return errors.New("该 k = " + k + " 存在 v" )
   }
}

func UnlockInstanceMap(k string){
   var rw sync.Mutex
   rw.Lock()
   defer rw.Unlock()
   InstanceMap = GetInstanceMap()
   InstanceMap[k] = nil

}

func GetKeyInstanceMap(k string)interface{}{
   var rw sync.Mutex
   rw.Lock()
   defer rw.Unlock()
   InstanceMap = GetInstanceMap()
   v := InstanceMap[k]
   return v
}

2> 上面这种方法还是有问题,当程序包部署两个地方,a的动作之后加锁,b接收到了a完成的动作,没办法解开map的锁,name基于客户端的缓存,此方法后续再讲

相关标签: