Distributed Locking

True distributed locking across multiple servers using Couchbase's native locking mechanism.

True distributed locking across multiple servers using Couchbase's native locking mechanism.

🎯 What is Distributed Locking?

Distributed locking ensures that only one process across your entire server cluster can execute a critical section of code at a time. This is essential for:

  • 💰 Financial transactions - Prevent double-charging or race conditions

  • 📦 Inventory updates - Avoid overselling products

  • 🔄 Batch processing - Ensure only one server runs the job

  • 🎫 Ticket sales - Prevent double-booking

  • 👤 User account updates - Serialize concurrent modifications

🚀 Quick Start

<bx:CouchbaseLock
    name="user-#userId#-update"
    cache="default"
    timeout="5"
    expires="30">

    // Critical section - only one request at a time
    user = getUser(userId);
    user.balance += amount;
    saveUser(user);

</bx:CouchbaseLock>

BIF with Callback

BIF Manual Mode

📖 How It Works

Lock Mechanism

Couchbase provides distributed locking using its getAndLock() API:

  1. Lock Document Created: A special document with prefix __lock:{cacheName}:{lockName}

  2. Exclusive Access: Couchbase ensures only one server can lock the document

  3. Automatic Expiry: Lock expires after specified duration (max 30 seconds)

  4. CAS-Based Unlock: Unlock requires the correct CAS value from acquisition

Lock Key Format

Example: __lock:sessionCache:user-123-update

🎨 Usage Patterns

Pattern 1: Component for Simple Cases

Best for straightforward critical sections with no complex logic:

Pattern 2: Callback for Return Values

When you need to return a value from the locked section:

Pattern 3: Manual for Complex Control

When you need fine-grained control over lock lifecycle:

💡 Real-World Examples

Example 1: Prevent Double-Charging

Example 2: Inventory Management

Example 3: Scheduled Job Coordination

Example 4: Sequential Document Processing

Example 5: Rate Limiting with Locks

⚙️ Configuration

Component Attributes

Attribute
Type
Required
Default
Description

name

String

Yes

-

Unique lock name across cluster

cache

String

Yes

-

Couchbase cache name

timeout

Integer

No

5

Seconds to wait for lock

expires

Integer

No

30

Lock expiration (max 30)

throwOnTimeout

Boolean

No

true

Throw exception on timeout

bypass

Boolean

No

false

Skip locking (for testing)

BIF Parameters

couchbaseLock():

  • cacheName (String, required) - Cache name

  • name (String, required) - Lock name

  • timeout (Integer, optional, default: 5) - Acquisition timeout in seconds

  • expires (Integer, optional, default: 30) - Lock expiration in seconds

  • callback (Function, optional) - Function to execute with lock held

  • throwOnTimeout (Boolean, optional, default: true) - Throw on timeout

couchbaseUnlock():

  • cacheName (String, required) - Cache name

  • name (String, required) - Lock name

  • cas (Long, required) - CAS value from lock acquisition

⚠️ Important Limitations

30 Second Maximum

Couchbase limits getAndLock() to 30 seconds maximum:

For operations longer than 30 seconds, consider:

  • Breaking into smaller locked operations

  • Using a different synchronization approach

  • Implementing a heartbeat/renewal pattern

Lock Expiration

Locks automatically expire after the specified duration. If your operation takes longer, the lock will be released:

Solution: Set expires longer than your operation needs.

🎭 Best Practices

✅ DO

Use descriptive lock names:

Keep critical sections short:

Always use try/finally with manual locks:

Set appropriate timeouts:

❌ DON'T

Don't use locks for caching:

Don't nest locks (deadlock risk):

Don't hold locks during I/O:

🔍 Testing

Bypass Mode

Use bypass=true for testing without actual locking:

Mock Scenarios

Test lock behavior with short timeouts:

🐛 Troubleshooting

Lock Timeout Errors

Problem: Failed to acquire lock within X seconds

Solutions:

  1. Increase timeout parameter

  2. Ensure locks are being released properly

  3. Check for deadlocks or stuck processes

  4. Verify lock expiration is appropriate

Stale Locks

Problem: Lock seems permanently held

Cause: Locks auto-expire after expires seconds

Solution:

  • Wait for expiration (max 30 seconds)

  • Or manually remove lock document:

Performance Impact

Problem: Locking adds latency

Solutions:

  1. Reduce lock duration - keep critical sections minimal

  2. Use shorter timeouts for better responsiveness

  3. Consider if locking is really needed

  4. Cache frequently-accessed data outside locks

📊 Monitoring

Monitor lock usage:

📚 See Also

Last updated

Was this helpful?