# Distributed Locking with Redis Implement mutual exclusion across distributed processes using `SET key value NX PX timeout` for atomic lock acquisition with automatic expiration. Distributed systems often need mutual exclusion to prevent race conditions when multiple processes access shared resources. This pattern covers single-instance locks, lock release with owner verification, and lock extension. ## The Basic Lock Redis locks use the SET command with special options: SET resource:lock NX PX 30000 This command: - Sets the key only if it doesn't exist (`NX`) - Sets a 30-second expiration (`PX 30000`) - Stores a unique token to identify the lock owner If the command returns OK, the lock was acquired. If it returns nil, another client holds the lock. ## Why These Options Matter **NX (Not Exists)**: Ensures only one client can acquire the lock. If two clients try simultaneously, only one succeeds. **PX (Expiration)**: Prevents deadlocks. If the lock holder crashes without releasing the lock, it automatically expires. Without expiration, a crashed client would hold the lock forever. **Token**: A random value (typically a UUID) that identifies this specific lock acquisition. This is crucial for safe release. ## Releasing the Lock Never release a lock with a simple DEL command: DEL resource:lock # DANGEROUS! This risks deleting another client's lock. Consider this scenario: 1. Client A acquires lock with token "abc" 2. Client A takes too long, lock expires 3. Client B acquires lock with token "xyz" 4. Client A finishes and calls DEL 5. Client A deletes Client B's lock! ## Safe Lock Release Use a Lua script that checks the token before deleting: if redis.call("get", KEYS[1]) == ARGV[1] then return redis.call("del", KEYS[1]) else return 0 end Execute with: EVAL