Skip to content

distributed-lock-spring-boot-starter is a distributed lock starter for Spring Boot, designed to provide reliable and extensible distributed locking capabilities for applications through minimal intrusion and a unified abstraction.

License

Notifications You must be signed in to change notification settings

ChildrenGreens/distributed-lock-spring-boot-starter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

27 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CircleCI codecov Maven Central Apache 2 Codacy code quality

Distributed-Lock-Spring-Boot-Starter

Overview

A Spring Boot starter that provides annotation-driven distributed locks via AOP. Supported backends: Redisson, Zookeeper (Curator), and Etcd (jetcd).

Features

  • @DistributedLock annotation for method-level locking

  • SpEL-based lock key resolution with sensible defaults

  • Multiple lock types: reentrant, fair, read, write

  • Auto-configuration based on available client beans

Requirements

  • Java 17+

  • Spring Boot 4.0.x

Versioning

  • Spring Boot 3.x users should use the 0.0.x release line

  • Spring Boot 4.x users should use the 0.1.x release line

Installation

Add the starter dependency and one backend client dependency.

Maven:

<dependency>
  <groupId>com.childrengreens</groupId>
  <artifactId>distributed-lock-spring-boot-starter</artifactId>
  <version>${latest-version}</version>
</dependency>

Backend dependencies (pick one or more):

<dependency>
  <groupId>org.redisson</groupId>
  <artifactId>redisson</artifactId>
  <version>4.0.0</version>
</dependency>
<dependency>
  <groupId>org.apache.curator</groupId>
  <artifactId>curator-recipes</artifactId>
  <version>5.9.0</version>
</dependency>
<dependency>
  <groupId>io.etcd</groupId>
  <artifactId>jetcd-core</artifactId>
  <version>0.8.6</version>
</dependency>

Configuration

Application properties:

distributed:
  lock:
    prefix: lock
  • distributed.lock.prefix (default: lock)

  • distributed.lock.provider (optional: redisson, zookeeper, etcd)

Usage

Annotate a method with @DistributedLock:

import com.childrengreens.distributedlock.annotation.DistributedLock;
import com.childrengreens.distributedlock.annotation.LockType;

@DistributedLock(key = "#orderId", prefix = "order", waitTime = 3, leaseTime = 10, lockType = LockType.FAIR)
public void process(String orderId) {
    // business logic
}

SpEL examples:

@DistributedLock(key = "#user.id + ':' + #order.id")
public void pay(User user, Order order) {
}

@DistributedLock(key = "@tenantProvider.tenantId + ':' + #p0")
public void handle(String id) {
}

Default key behavior: - If key is empty, the key is generated as:

+ DeclaringClass.methodName:<SimpleKey>

Prefix behavior: - @DistributedLock(prefix = "...") overrides distributed.lock.prefix - If both are empty, no prefix is used

Provider selection: - Set distributed.lock.provider to pick the backend when multiple clients exist

Backend Setup

The starter auto-configures the executor when a client bean exists.

Redisson

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
class RedissonConfig {
    @Bean
    RedissonClient redissonClient() {
        Config config = new Config();
        config.useSingleServer().setAddress("redis://127.0.0.1:6379");
        return Redisson.create(config);
    }
}

Zookeeper (Curator)

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
class CuratorConfig {
    @Bean(initMethod = "start", destroyMethod = "close")
    CuratorFramework curatorFramework() {
        return CuratorFrameworkFactory.newClient(
            "127.0.0.1:2181",
            new ExponentialBackoffRetry(1000, 3)
        );
    }
}

Etcd (jetcd)

import io.etcd.jetcd.Client;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
class EtcdConfig {
    @Bean(destroyMethod = "close")
    Client etcdClient() {
        return Client.builder().endpoints("http://127.0.0.1:2379").build();
    }
}

Lock Types

  • REENTRANT: default reentrant lock

  • FAIR: fair lock when supported

  • READ: read lock (read/write lock)

  • WRITE: write lock (read/write lock)

Mapping notes: - Redisson: maps directly to the respective lock variants - Zookeeper: FAIR uses a reentrant mutex implementation - Etcd: uses a single lock type; LockType is tracked for unlock bookkeeping

Error Handling

  • If a lock cannot be acquired, a DistributedLockException is thrown

  • Unlock failures are logged and suppressed to avoid masking business errors

Customization

Provide your own DistributedLockExecutor bean to override auto-configuration. You can also replace LockKeyResolver if you need custom key resolution logic.

About

distributed-lock-spring-boot-starter is a distributed lock starter for Spring Boot, designed to provide reliable and extensible distributed locking capabilities for applications through minimal intrusion and a unified abstraction.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages