Distributed Locking

Implement distributed locking in BoxLang applications using Redis to prevent concurrent access issues.

🔒 Overview

In clustered environments, it is often necessary to prevent multiple instances from executing methods at the same time, preventing collisions with data access and modification. The bx:RedisLock component provides distributed locking across all running instances in a cluster using Redis as the coordination mechanism.

The component functions similarly to the standard lock component but uses Redis to coordinate locks across multiple servers, ensuring that only one request can execute the locked code at any given time across the entire cluster.

📋 Component Syntax

<bx:RedisLock
    name="lockName"
    cache="redisCacheName"
    timeout="2"
    expires="60"
    throwOnTimeout="true"
    bypass="false"
>
    <!-- Protected code here -->
</bx:RedisLock>

Script Syntax:

bx:redisLock name="lockName" cache="redisCacheName" timeout=2 expires=60 throwOnTimeout=true bypass=false {
    // Protected code here
}

⚙️ Attributes

Attribute
Type
Required
Default
Description

name

string

✅ Yes

-

Lock name. Only one request can execute code within a lock with a given name at a time. Cannot be an empty string.

cache

string

✅ Yes

-

The name of the Redis cache (as defined in application cache settings) to use for the lock

timeout

integer

No

2

Maximum time in seconds to wait to obtain a lock. Must be >= 0. If lock is not obtained within this time, behavior depends on throwOnTimeout.

expires

integer

No

60

The length of time in seconds before the lock automatically expires. Must be >= 1. Prevents deadlocks if a process crashes while holding a lock.

throwOnTimeout

boolean

No

true

If true, throws a runtime exception if lock is not obtained within timeout period. If false, skips the body and continues execution.

bypass

boolean

No

false

If true, bypasses the lock entirely and executes the body immediately. Useful for development environments.

💡 Usage Examples

Basic Distributed Lock

Lock with Timeout Handling

Development Bypass

XML Component Syntax

🎯 Common Use Cases

Scheduled Task Coordination

Cache Warming

Database Migration Coordination

Sequential Processing

🔧 Configuration Requirements

Cache Setup

The lock requires a configured Redis cache in your application:

Cluster Configuration

For multi-server environments, ensure all servers point to the same Redis instance:

⚠️ Best Practices

Lock Naming

  • Use descriptive, unique lock names

  • Include context in name: "user_#{userId}_update" instead of "update"

  • Avoid hardcoded IDs - use dynamic names when locking specific resources

Timeout Configuration

  • Set timeout based on expected wait time

  • Set expires longer than maximum expected execution time

  • Use throwOnTimeout=false for non-critical operations

Error Handling

  • Always handle exceptions within locked code

  • Keep locked code sections as short as possible

  • Consider using try/catch inside lock body

Development vs Production

  • Use bypass attribute for development environments

  • Set via environment variables or application settings

🚨 Troubleshooting

Lock Not Acquired

Symptoms: throwOnTimeout exceptions or body not executing

Solutions:

  • Increase timeout value

  • Check if another process is holding the lock too long

  • Verify Redis connectivity

  • Check Redis logs for connection issues

Deadlocks

Symptoms: Locks never release, operations hang

Solutions:

  • Ensure expires is set appropriately

  • Verify locked code completes normally

  • Check for infinite loops in locked sections

  • Monitor Redis for stuck lock keys

Performance Issues

Symptoms: High latency acquiring locks

Solutions:

  • Reduce lock scope - lock smaller code sections

  • Increase Redis server resources

  • Check network latency to Redis

  • Consider Redis Cluster for high-availability

Cache Not Found

Error: "The specified cache [name] is not a Redis cache"

Solutions:

  • Verify cache name matches application configuration

  • Ensure cache provider type is "Redis"

  • Check cache is properly initialized before use

🔍 Monitoring

Lock Metrics

Monitor these aspects of distributed locking:

  • Lock acquisition time - time spent waiting for locks

  • Lock hold duration - time locks are held

  • Failed acquisitions - locks that timeout

  • Lock expiration events - automatic releases

Redis Key Inspection

Locks are stored in Redis with specific key patterns. Use Redis CLI to inspect:

Last updated

Was this helpful?