Mastering tldb Distributed Locks in Go and Java: A Practical Guide
This article explains how tldb implements distributed locks, details the lock, tryLock, and unlock APIs, and provides step‑by‑step Go and Java code examples—including blocking, non‑blocking, and spin‑lock patterns—plus test results to illustrate correct usage.
Distributed locks are essential in distributed systems, and tldb offers a simple, reliable lock mechanism that mimics object‑level locking.
tldb Distributed Lock API
lock(string, int) : blocks until the lock is acquired; the first argument is the lock name, the second is the maximum hold time in seconds.
tryLock(string, int) : attempts to acquire the lock and returns immediately; if successful, it returns a key, otherwise an empty result.
unlock(string) : releases the lock using the key returned by lock/tryLock.
The lock functions are implemented in the MQ module, and client libraries exist for Java, Go, Python, and JavaScript. The lock is server‑controlled, making it language‑agnostic.
Lock (string, int) Usage
The first parameter specifies the lock object (e.g., "abc"), and the second parameter defines the lock’s maximum lease time in seconds. If the lease expires without an explicit unlock, the server forcibly releases the lock.
Unlock(string) Usage
After completing business logic, the client must call unlock(key) to release the lock; otherwise, the server will release it after the timeout.
TryLock (string, int) Usage
Unlike lock, tryLock is non‑blocking; it returns immediately with a key if the lock is obtained, or an empty result if the lock is already held.
Go Example
import "github.com/donnie4w/tlmq-go/cli"
// Blocking lock
sc := cli.NewMqClient("ws://127.0.0.1:5001", "mymq=123")
sc.Connect()
key, err := sc.Lock("testlock", 3)
if err != nil {
// handle error
} else {
defer sc.UnLock(key)
// business logic
}
// Non‑blocking tryLock
if key, ok := sc.TryLock("testlock2", 3); ok {
defer sc.UnLock(key)
// business logic
}
// Spin‑lock using tryLock
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)
// business logicJava Example
Maven dependency:
<dependency>
<groupId>io.github.donnie4w</groupId>
<artifactId>tlmq-j</artifactId>
<version>0.0.2</version>
</dependency>Blocking lock:
MqClient mc = new SimpleClient("ws://127.0.0.1:5001", "mymq=123");
mc.connect();
String key = null;
try {
key = mc.lock("testlock", 3);
// business logic
} finally {
if (key != null) {
mc.unLock(key);
}
}Non‑blocking tryLock:
MqClient mc = new SimpleClient("ws://127.0.0.1:5001", "mymq=123");
mc.connect();
String key = null;
try {
key = mc.tryLock("testlock", 3);
// business logic
} finally {
if (key != null) {
mc.unLock(key);
}
}Functional Test Results
Concurrent threads acquiring the same lock using lock and tryLock produce the following outcomes:
Spinning with tryLock to emulate blocking behavior yields:
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Programmer DD
A tinkering programmer and author of "Spring Cloud Microservices in Action"
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
