分布式锁是一种在分布式系统中用于控制多个进程/节点对共享资源进行互斥访问的机制。它解决了在分布式环境下协调不同服务或节点之间同步操作的问题。

magic-spring-boot-starter-protection 提供了基于 Redis 实现的分布式锁 ,它有 2 种使用方式:

  • 编程式锁:Redisson 内置的 RedissonClient 提供的分布式锁 API

  • 声明式锁:基于 Lock4j 框架的 @Lock4j 注解

# 1 编程式锁

当我们通过 spring data redis 和 Redisson 整合后,可以使用 Redisson 的高级特性。

@RestController
@Slf4j
public class DefaultController {

    @Autowired
    private RedissonClient redissonClient;

    @RequestMapping(value = {"/test"})
    @PermitAll
    public CommonResult<Boolean> test(HttpServletRequest request) {
        // 打印查询参数
        Lock lock = redissonClient.getLock("testLock");
        try {
            lock.lock();
            
            // 省略的业务逻辑代码
            
        } finally {
            if (lock != null && lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
        return CommonResult.success(true);
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

上面的代码里 ,展示了一个典型的 Redisson 分布式锁的使用示例。

1、获取锁对象

// 从Redisson客户端获取锁对象,指定锁名称
Lock lock = redissonClient.getLock("yourLockName");
1
2

2、加锁并执行业务逻辑

try {
    // 加锁(默认30秒自动释放)
    lock.lock();
    // 或者指定锁超时时间:lock.lock(10, TimeUnit.SECONDS);
    
    // 在这里执行需要互斥的业务逻辑
    // 例如:
    // - 库存扣减
    // - 订单状态变更
    // - 防止重复处理
    
} finally {
    // 确保锁被释放
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

3、释放锁

finally {
    if (lock != null) {
        lock.unlock();
    }
}
1
2
3
4
5

# 2 Lock4j 框架

Lock4j 是一款基于Spring AOP 的声明式和编程式分布式锁,支持 RedisTemplate、Redisson、Zookeeper 。

Github地址:https://github.com/baomidou/lock4j

magic-spring-boot-starter-protection 组件依赖了 lock4j 框架:

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>lock4j-redisson-spring-boot-starter</artifactId>
    <optional>true</optional>
</dependency>
1
2
3
4
5

然后在 application-local.yaml 配置文件中,通过 lock4j 配置项,添加 Lock4j 全局默认的分布式锁配置。如下图所示:

最后在需要分布式的地方使用 Lock4j 注解。

@Service
public class DemoService {

    //默认获取锁超时3秒,30秒锁过期
    @Lock4j
    public void simple() {
        //do something
    }

    //完全配置,支持spel
    @Lock4j(keys = {"#user.id", "#user.name"}, expire = 60000, acquireTimeout = 1000)
    public User customMethod(User user) {
        return user;
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
上次更新: 2026/6/28