lock4j Documentation

repository·master·Indexed 19 days ago

https://github.com/baomidou/lock4j

A high-performance distributed lock component for Java and Spring Boot. It supports multiple backends including Redisson, RedisTemplate, and Zookeeper. lock4j provides an annotation-based programming model via @Lock4j, a programmatic API using LockTemplate, and extension points for custom executors, key builders, and failure strategies.

Tokens
2.8K
Snippets
8
Records
9
Agent score
64%

What's inside lock4j

  1. Extend lock4j: Custom Executor, Key Builder, and Failure Strategy

    master

    lock4j provides several extension points:

    1. Custom Executor: Implement your own lock executor and specify it in the @Lock4j(executor = ...) annotation. Ensure the implementation is registered as a Spring Bean.

    2. Custom Lock Key Builder: Extend com.baomidou.lock.DefaultLockKeyBuilder and override buildKey to change how lock keys are generated.

    3. Custom Lock Failure Strategy: Implement the LockFailureStrategy interface and override onLockFailure to define custom behavior when a lock cannot be acquired. The default is com.baomidou.lock.DefaultLockFailureStrategy.

    // Custom Key Builder
    @Component
    public class MyLockKeyBuilder extends DefaultLockKeyBuilder {
        @Override
        public String buildKey(MethodInvocation invocation, String[] definitionKeys) {
            String key = super.buildKey(invocation, definitionKeys);
            // custom logic
            return key;
        }
    }
    
    // Custom Failure Strategy
    @Component
    public class MyLockFailureStrategy implements LockFailureStrategy {
        @Override
        public void onLockFailure(String key, long acquireTimeout, int acquireCount) {
            // custom logic
        }
    }
  2. Install lock4j via Maven

    master

    To use lock4j, include the appropriate starter dependency for your chosen distributed lock implementation. You can include multiple starters if you need different lock implementations for different methods.

    Available starters:

    • lock4j-redis-template-spring-boot-starter for redisTemplate implementation.
    • lock4j-redisson-spring-boot-starter for redisson implementation.
    • lock4j-zookeeper-spring-boot-starter for zookeeper implementation.
    <dependencies>
        <!-- If using redisTemplate as the underlying distributed lock -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>lock4j-redis-template-spring-boot-starter</artifactId>
            <version>${latest.version}</version>
        </dependency>
        <!-- If using redisson as the underlying distributed lock -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>lock4j-redisson-spring-boot-starter</artifactId>
            <version>${latest.version}</version>
        </dependency>
        <!-- If using zookeeper as the underlying distributed lock -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>lock4j-zookeeper-spring-boot-starter</artifactId>
            <version>${latest.version}</version>
        </dependency>
    </dependencies>
  3. Configure lock4j global settings

    master

    You can configure global defaults in your application.yml file.

    Key properties:

    • lock4j.acquire-timeout: Default wait time in queue (ms). Default is 3000.
    • lock4j.expire: Default lock expiration time (ms) to prevent deadlocks. Default is 30000.
    • lock4j.primary-executor: The default executor to use if none is specified in the annotation. Order of preference: RedissonLockExecutor > RedisTemplateLockExecutor > ZookeeperLockExecutor.
    • lock4j.lock-key-prefix: Prefix for all lock keys. Default is lock4j.
    lock4j:
      acquire-timeout: 3000
      expire: 30000
      primary-executor: com.baomidou.lock.executor.RedisTemplateLockExecutor
      lock-key-prefix: lock4j
  4. Enable Redisson-based distributed locking via Spring Boot Starter

    master

    When using the lock4j-redisson-spring-boot-starter, the RedissonLockExecutor is automatically configured and available in the Spring application context if Redisson is present on the classpath. This executor uses an existing RedissonClient bean to provide distributed locking capabilities. You can inject RedissonLockExecutor into your services to manage distributed locks.

    @Service
    public class MyService {
        @Autowired
        private RedissonLockExecutor redissonLockExecutor;
    
        public void doSomething() {
            // Use the injected executor to perform locking operations
        }
    }
  5. Use the @Lock4j annotation for distributed locking

    master

    Apply the @Lock4j annotation to methods that require distributed locking.

    Basic Usage: Uses default settings (3s acquire timeout, 30s lock expiration).

    Advanced Configuration:

    • keys: An array of SpEL expressions to generate the lock key (e.g., #user.id).
    • expire: Lock expiration time in milliseconds (prevents deadlocks).
    • acquireTimeout: Maximum time (ms) to wait in queue for the lock before failing.
    • executor: Specify a specific lock executor class (e.g., RedissonLockExecutor.class).
    • autoRelease: If set to false, the lock will not be automatically released, which can be used for rate limiting (e.g., allowing only one access every 5 seconds).
    @Service
    public class DemoService {
    
        // Default: 3s acquire timeout, 30s expiration
        @Lock4j
        public void simple() {
            // do something
        }
    
        // Custom configuration with SpEL keys
        @Lock4j(keys = {"#user.id", "#user.name"}, expire = 60000, acquireTimeout = 1000)
        public User customMethod(User user) {
            return user;
        }
    
        // Rate limiting: User can only access once every 5 seconds
        @Lock4j(keys = {"#user.id"}, acquireTimeout = 0, expire = 5000, autoRelease = false)
        public Boolean test(User user) {
            return "true";
        }
    }
  6. Perform programmatic locking with LockTemplate

    master

    If annotation-based locking is not suitable, use LockTemplate to manually acquire and release locks.

    1. Inject LockTemplate into your service.
    2. Call lockTemplate.lock(key, expire, acquireTimeout, executorClass).
    3. If the returned LockInfo is not null, the lock was acquired.
    4. Wrap your business logic in a try-finally block and call lockTemplate.releaseLock(lockInfo) in the finally block to ensure the lock is released.
    @Service
    public class ProgrammaticService {
        @Autowired
        private LockTemplate lockTemplate;
    
        public void programmaticLock(String userId) {
            // Acquire lock: key, expire (ms), acquireTimeout (ms), executor
            final LockInfo lockInfo = lockTemplate.lock(userId, 30000L, 5000L, RedissonLockExecutor.class);
            
            if (null == lockInfo) {
                throw new RuntimeException("Business processing in progress, please try again later");
            }
    
            try {
                // Execute business logic
                System.out.println("Executing logic...");
            } finally {
                // Release the lock
                lockTemplate.releaseLock(lockInfo);
            }
        }
    }
  7. Configure Zookeeper distributed lock settings

    master

    When using the lock4j-zookeeper-spring-boot-starter, you can configure the Zookeeper connection and retry behavior using properties prefixed with spring.coordinate.zookeeper.

    These settings control how the underlying CuratorFramework client connects to your Zookeeper ensemble and how it handles retries during connection failures.

    spring:
      coordinate:
        zookeeper:
          zkServers: "127.0.0.1:2181,127.0.0.1:2182"
          sessionTimeout: 30000
          connectionTimeout: 5000
          baseSleepTimeMs: 1000
          maxRetries: 3
  8. Use ZookeeperLockExecutor for distributed locking

    master

    The ZookeeperLockExecutor is automatically registered in the Spring context when the Zookeeper starter is present and the Zookeeper connection properties are configured. You can inject this bean into your services to perform distributed locking operations using Zookeeper as the coordination backend.

    @Service
    public class MyService {
        @Autowired
        private ZookeeperLockExecutor lockExecutor;
    
        public void doWork() {
            // Use the executor to manage locks
        }
    }
  9. Reference: Zookeeper configuration properties

    master

    The following properties are available under the spring.coordinate.zookeeper prefix for configuring the Zookeeper client:

    PropertyTypeDefaultDescription
    zkServersStringRequiredThe connection string for the Zookeeper ensemble (e.g., host:port,host:port).
    sessionTimeoutint30000The session timeout in milliseconds.
    connectionTimeoutint5000The connection timeout in milliseconds.
    baseSleepTimeMsint1000The base sleep time for the ExponentialBackoffRetry policy in milliseconds.
    maxRetriesint3The maximum number of retries for the connection attempt.