3.unlock 释放已经获取的锁
tldb 提供的分布式锁功能主要在 MQ 模块中实现,调用的方法在 MQ 客户端实现,客户端的实现实际非常简单,除了目前已经实现的几种语言 java,golang,python,javaScript 写的 simpleClient,其实其他开发者有兴趣也可以实现其他语言的 MQ 客户端,完全没有技术门槛。分布式锁由 tldb 服务器控制,所以它相对客户端来说,也是跨语言的,如,用 java 客户端上锁的对象,其他语言同样无法获取该对象锁。
第二个参数为持有该分布式锁的最长时间,单位为秒,例如 lock ("abc",3),意思是,如果超过 3 秒还没有调用 unlock 释放该锁,服务器将强制释放该锁,继续将锁分配给其他请求的线程。
UnLock 为释放分布式锁时调用的方法。客户端在成功获取分布式锁后,服务器会返回一个该锁的 key,客户端执行完逻辑代码的最后,必须显式调用 UnLock (key) 来释放该分布式锁。如果没有调用 unlock 释放锁,tldb 将等待锁释放的超时时间直至超时后强制释放该锁。
trylock 与 lock 相似,但是 lock 方法阻塞的,调用 lock 方法请求分布式锁时,如果该锁已经被占用,那么 lock 方法将一直等待直至 tldb 服务器将锁分配给它,这与程序中获取独占锁的方式一致。而 trylock 时非阻塞的,调用 trylock 后会立即返回,如果获取到锁,tldb 会将标识该锁的 key 一并返回,如何该锁已经被占用,服务器将返回空数据。
import "github.com/donnie4w/tlmq-go/cli"调用 lock 的程序:lock 方法是阻塞的
sc := cli.NewMqClient("ws://127.0.0.1:5001", "mymq=123") sc.Connect() //以上为 客户端连接MQ服务器 key, err := sc.Lock("testlock", 3) //lock中两个参数,第一个参数为字符串,即tldb服务器为“testlock”分配一个全局的分布式锁 //第二个参数3为客户端持有该锁的最长时间,表示超过3秒没有释放锁时,tldb服务器将在服务端强制释放该锁,并分配给其他请求锁的线程 if err!=nil{ //获取锁失败,需查看tldb能正常访问 }else{ defer sc.UnLock(key) //获取锁成功后,必须在程序最后调用Unlock //执行业务逻辑程序 }调用 tryLock 的程序,trylock 是非阻塞的
sc := cli.NewMqClient("ws://127.0.0.1:5001", "mymq=123") sc.Connect() if key, ok := sc.TryLock("testlock2", 3); ok { //ok为true,表示已经成功获取到分布式锁 defer sc.UnLock(key) //在程序最后释放锁对象 ... }go 用自旋的方式使用 trylock 获取分布式锁,实现程序的阻塞等待
sc := cli.NewMqClient("ws://127.0.0.1:5001", "mymq=123") sc.Connect() var key string for { if v, ok := sc.TryLock("testlock", 3); ok { key = v break } else { <-time.After(100* time.Millisecond) } } defer sc.UnLock(key) ...//业务逻辑代码这段程序应该比较易于理解,就是每隔 100 毫秒,循环获取字符串 “testlock” 的分布式锁直至成功。
<dependency> <groupId>io.github.donnie4w</groupId> <artifactId>tlmq-j</artifactId> <version>0.0.2</version> </dependency>调用 lock 方法
MqClient mc = new SimpleClient("ws://127.0.0.1:5001", "mymq=123"); mc.connect(); //java连接服务器 String key = null; try{ key = mc.lock("testlock", 3); //获取分布式 ... //执行业务逻辑程序 }finally { if (key!=null){ mc.unLock(key); //释放分布式锁 } }调用 trylock 方法
MqClient mc = new SimpleClient("ws://127.0.0.1:5001", "mymq=123"); mc.connect(); String key = null; try{ key = mc.tryLock("testlock", 3); //获取分布式 ... //执行业务逻辑程序 } finally { if (key!=null){ mc.unLock(key); //释放分布式锁 } }以下是 tldb 分布式锁的功能测试数据: 多线程并发 调用 lock 获取同一个对象锁后,程序的运行数据: