欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 幼教 > Spring Boot 整合 Lock4j + Redisson 实现分布式锁实战

Spring Boot 整合 Lock4j + Redisson 实现分布式锁实战

2025/9/21 0:13:54 来源:https://blog.csdn.net/qq_42322632/article/details/147472036  浏览:    关键词:Spring Boot 整合 Lock4j + Redisson 实现分布式锁实战

本文基于 Spring Boot 2.7.x + MyBatis Plus 3.5.9,演示如何通过 Lock4j 与 Redisson 实现高可靠的分布式锁方案,解决高并发场景下的资源竞争问题。


一、依赖配置关键点

1.1 Maven 依赖(pom.xml)

			 <dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><version>3.41.0</version><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></exclusion><exclusion><groupId>org.redisson</groupId><!-- 使用 redisson-spring-data-27 替代,解决 Tuple NoClassDefFoundError 报错 --><artifactId>redisson-spring-data-34</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-data-27</artifactId><version>3.41.0</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>lock4j-redisson-spring-boot-starter</artifactId><version>2.2.7</version><exclusions><exclusion><artifactId>redisson-spring-boot-starter</artifactId><groupId>org.redisson</groupId></exclusion></exclusions></dependency>

1.2 依赖关系说明

依赖作用版本控制策略
lock4j-redisson-*Lock4j 分布式锁核心实现继承自项目 BOM 统一管理
redisson-spring-boot-starterRedisson 客户端 Starter显式指定版本保证兼容性
redisson-spring-data-27Spring Data 2.7 适配模块与 Spring Boot 2.7.x 版本严格对应

二、为什么需要显式排除依赖?

2.1 解决版本冲突问题

  • Lock4j 默认依赖的 Redisson 版本可能较低,通过 <exclusions> 排除后使用项目统一管理的 Redisson 3.41.0
  • Spring Data 版本适配:Spring Boot 2.7.x 对应 Spring Data 2.7,需使用 redisson-spring-data-27 模块

2.2 避免不必要依赖

  • 排除 spring-boot-starter-actuator:若项目未使用监控端点,减少无用依赖
  • 排除 redisson-spring-data-34:防止与 Spring Data 2.7 产生兼容性问题

三、配置验证(application.yml)

spring:# Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优redis:host: 127.0.0.1 # 地址port: 6379 # 端口database: 0 # 数据库索引password: 123456 # 密码,建议生产环境开启
# Lock4j 配置项
lock4j:acquire-timeout: 3000 # 获取锁等待超时时间,默认为 3000 毫秒expire: 30000 # # 默认锁过期时间(毫秒),默认为 30 毫秒store-type: redis # 使用 Redis 实现

四、锁失败策略配置(核心防御机制)

4.1 DefaultLockFailureStrategy 源码解析

/*** 自定义获取锁失败策略,抛出 {@link ServiceException} 异常*/
@Slf4j
public class DefaultLockFailureStrategy implements LockFailureStrategy {@Overridepublic void onLockFailure(String key, Method method, Object[] arguments) {log.debug("[onLockFailure][线程:{} 获取锁失败,key:{} 获取失败:{} ]", Thread.currentThread().getName(), key, arguments);throw new ServiceException(GlobalErrorCodeConstants.LOCKED);}
}

关键设计点:

  • 日志分级:使用 debug 级别避免生产环境日志膨胀
  • 异常标准化:通过 GlobalErrorCodeConstants.LOCKED 统一返回 “请求过于频繁” 提示
  • 上下文保留:记录线程、锁Key、方法参数等关键信息便于问题排查

五、自动装配机制(集成关键)

5.1 DyhLock4jConfiguration 配置类

@AutoConfiguration(before = LockAutoConfiguration.class)
@ConditionalOnClass(name = "com.baomidou.lock.annotation.Lock4j")
public class DyhLock4jConfiguration {@Beanpublic DefaultLockFailureStrategy lockFailureStrategy() {return new DefaultLockFailureStrategy();}}

注解解析:

注解作用
@AutoConfigurationSpring Boot 3.0+ 新特性,替代传统 @Configuration 更精准控制加载顺序
before = LockAutoConfiguration.class确保在 Lock4j 默认配置前加载,避免 Bean 冲突
@ConditionalOnClass存在 Lock4j 注解时才生效,实现条件化装配

5.2 配置类加载流程说明

流程分解

1. Spring Boot 启动│└─▶ 扫描所有 AutoConfiguration 类│├─▶ 检测是否存在 Lock4j 注解(@ConditionalOnClass)│    ││    ├─ 存在 → 加载 DyhLock4jConfiguration│    │       ││    │       └─▶ 注册 DefaultLockFailureStrategy Bean│    │              ││    │              └─▶ 初始化 Lock4j 组件│    ││    └─ 不存在 → 跳过分布式锁配置│└─▶ 继续其他自动配置

关键节点说明

步骤说明对应代码片段
条件检测@ConditionalOnClass 注解检查 classpath 是否存在 com.baomidou.lock.annotation.Lock4j 类@ConditionalOnClass(name = “com.baomidou.lock.annotation.Lock4j”)
配置顺序控制@AutoConfiguration(before = LockAutoConfiguration.class) 确保自定义配置在 Lock4j 默认配置前加载@AutoConfiguration(before = LockAutoConfiguration.class)
Bean 注册通过 @Bean 注解将失败策略注入 Spring 容器@Bean public DefaultLockFailureStrategy lockFailureStrategy()

六、实战开发示例

@Service
@RequiredArgsConstructor
public class OrderService {private final OrderMapper orderMapper;// 分布式锁注解@Lock4j(name = "order_create_#{#orderDTO.userId}", // 动态锁名(SpEL)expire = 10000,      // 锁自动释放时间(毫秒)acquireTimeout = 2000 // 获取锁等待时间)@Transactionalpublic void createOrder(OrderDTO orderDTO) {// 1. 幂等校验Order existOrder = orderMapper.selectByUserId(orderDTO.getUserId());if (existOrder != null) {throw new ServiceException("订单已存在");}// 2. 业务操作(如扣减库存)reduceStock(orderDTO.getProductId());// 3. 创建订单Order order = new Order().setUserId(orderDTO.getUserId());orderMapper.insert(order);}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词