patterntypescriptMajor
Distributed locking with Redis SETNX: acquire, execute, release with TTL safety
Viewed 0 times
redlock ^5.x, ioredis ^5.x
distributed lockredisredlocksetnxttlrace conditionmutual exclusionlua script
Error Messages
Problem
Multiple service instances race to process the same resource (e.g., scheduled job, inventory allocation). A database-level transaction is not sufficient because the lock must span multiple services.
Solution
Use Redis SET with NX (only if not exists) and PX (TTL in ms) to implement a distributed lock. Release the lock only if the token matches (Lua script for atomicity). Use Redlock for multi-node Redis setups.
import Redlock from 'redlock';
const redlock = new Redlock([redis]);
async function processJob(jobId: string) {
const lock = await redlock.acquire([`lock:job:${jobId}`], 5000); // 5s TTL
try {
await doWork(jobId);
} finally {
await lock.release();
}
}Why
The TTL ensures the lock is released even if the holder crashes. The token comparison prevents a late releaser from releasing a lock acquired by another instance after TTL expiry.
Gotchas
- The lock TTL must be longer than the expected operation duration — but not so long that failures cause long blocking
- Redlock on a single Redis node is not truly safe; use 3-5 Redis nodes for the Redlock quorum algorithm
- A lock does not prevent stale reads — combine with optimistic locking (version column) for database operations
- Extend the lock if work takes longer than expected — Redlock supports lock extension
Context
Multiple service instances competing to process a shared resource (scheduled jobs, inventory, coupons)
Revisions (0)
No revisions yet.