# lockDemo **Repository Path**: xiaoxiaoi/lock-demo ## Basic Information - **Project Name**: lockDemo - **Description**: 使用redission客户端通过注解获取分布式锁 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-01-09 - **Last Updated**: 2026-01-09 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 分布式锁 Demo 基于 Spring Boot + Redisson 实现的分布式锁框架,通过 AOP 切面和注解方式提供简单易用的分布式锁功能。 ## 技术栈 - Spring Boot 2.7.18 - Redisson 3.24.0 - Redis - Spring AOP - Java 11 ## 功能特性 - ✅ 基于注解的分布式锁,使用简单 - ✅ 支持多种锁类型(普通锁、公平锁、读写锁) - ✅ 支持多种锁策略(快速失败、重试、一直等待) - ✅ 灵活配置等待时间和锁租期 - ✅ 自动锁释放,防止死锁 - ✅ AOP 切面自动处理加锁解锁逻辑 ## 快速开始 ### 1. 配置 Redis 编辑 `application.yaml`: ```yaml spring: redis: host: localhost port: 6379 password: your_password timeout: 10000 connect-timeout: 10000 ``` ### 2. 使用 @Lock 注解 在需要加锁的方法上添加 `@Lock` 注解: ```java @Service public class OrderService { @Lock( name = "order:lock", // 锁名称 waitTime = 10, // 等待时间 leaseTime = 30, // 锁租期(-1表示自动续期) timeUnit = TimeUnit.SECONDS, // 时间单位 lockType = LockType.DEFAULT, // 锁类型 lockStrategy = LockStrategy.RETRY_TIMEOUT_FAIL // 锁策略 ) public void createOrder() { // 业务逻辑 } } ``` ## 锁类型说明 ### LockType(锁类型) | 类型 | 说明 | 使用场景 | |------|------|----------| | `DEFAULT` | 普通可重入锁 | 一般业务场景 | | `FAIR_LOCK` | 公平锁 | 需要按顺序获取锁的场景 | | `READ_LOCK` | 读锁 | 读多写少,允许多个读操作并发 | | `WRITE_LOCK` | 写锁 | 需要独占访问的写操作 | ### LockStrategy(锁策略) | 策略 | 说明 | 行为 | |------|------|------| | `FAST_SKIP` | 快速跳过 | 获取锁失败立即返回 false,不重试 | | `FAST_FAIL` | 快速失败 | 获取锁失败立即抛出异常,不重试 | | `RETRY_TIMEOUT_SKIP` | 超时跳过 | 在 waitTime 内重试获取锁,超时返回 false | | `RETRY_TIMEOUT_FAIL` | 超时失败 | 在 waitTime 内重试获取锁,超时抛出异常 | | `KEEP_TRYING` | 一直重试 | 一直尝试获取锁,直到成功(慎用) | ## 参数说明 ### @Lock 注解参数 | 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `name` | String | "lock" | 锁的名称,建议使用业务相关的唯一标识 | | `waitTime` | int | 1 | 获取锁的最大等待时间 | | `leaseTime` | int | -1 | 锁的租期,-1 表示使用看门狗自动续期 | | `timeUnit` | TimeUnit | SECONDS | 时间单位 | | `lockType` | LockType | DEFAULT | 锁类型 | | `lockStrategy` | LockStrategy | FAST_SKIP | 锁策略 | ### 时间参数详解 - **waitTime(等待时间)**:尝试获取锁时的最大等待时间 - **leaseTime(租期时间)**: - `> 0`:锁的持有时间,到期自动释放 - `-1`:启用 Redisson 看门狗机制,自动续期直到手动释放 ## 使用示例 ### 示例 1:防止重复提交 ```java @Lock( name = "submit:#{userId}", lockStrategy = LockStrategy.FAST_FAIL ) public void submitForm(Long userId) { // 表单提交逻辑 } ``` ### 示例 2:库存扣减 ```java @Lock( name = "stock:#{productId}", waitTime = 5, lockStrategy = LockStrategy.RETRY_TIMEOUT_FAIL ) public void decreaseStock(Long productId, int quantity) { // 库存扣减逻辑 } ``` ### 示例 3:公平锁场景 ```java @Lock( name = "queue:service", lockType = LockType.FAIR_LOCK, lockStrategy = LockStrategy.KEEP_TRYING ) public void processQueue() { // 队列处理逻辑 } ``` ### 示例 4:读写锁 ```java // 读操作 @Lock( name = "data:cache", lockType = LockType.READ_LOCK ) public Data readData() { return dataRepository.findAll(); } // 写操作 @Lock( name = "data:cache", lockType = LockType.WRITE_LOCK ) public void writeData(Data data) { dataRepository.save(data); } ``` ## 项目结构 ``` lockDemo/ ├── src/main/java/cn/xiao/lockdemo/ │ ├── config/ │ │ └── RedissonConfig.java # Redisson 配置 │ ├── controller/ │ │ └── LockController.java # 控制器 │ ├── service/ │ │ ├── LockService.java # 服务接口 │ │ └── impl/ │ │ └── LockServiceImpl.java # 服务实现 │ ├── util/ │ │ ├── Lock.java # 锁注解 │ │ ├── LockType.java # 锁类型枚举 │ │ ├── LockStrategy.java # 锁策略枚举 │ │ └── LockAspect.java # AOP 切面 │ └── LockDemoApplication.java # 启动类 └── src/main/resources/ └── application.yaml # 配置文件 ``` ## 注意事项 1. **锁名称建议**:使用业务相关的唯一标识,如 `order:{orderId}` 或 `user:{userId}` 2. **leaseTime 设置**: - 业务执行时间可预估时,设置具体值防止死锁 - 业务执行时间不确定时,使用 -1 启用自动续期 3. **锁策略选择**: - 高并发场景推荐 `FAST_SKIP` 或 `FAST_FAIL` - 需要保证执行的场景使用 `RETRY_TIMEOUT_FAIL` - 慎用 `KEEP_TRYING`,可能造成线程长时间阻塞 4. **Redis 连接**:确保 Redis 服务可用且网络稳定 5. **异常处理**:业务代码中注意处理锁获取失败的情况 ## 测试 启动项目后访问: ```bash curl http://localhost:8080/lock ``` ## 常见问题 ### Q1: 切面不生效? **A:** 确保 `LockAspect` 类添加了 `@Component` 注解,并且 pom.xml 包含 `spring-boot-starter-aop` 依赖。 ### Q2: RedissonClient 无法注入? **A:** 检查 `RedissonConfig` 配置类是否正确创建,Redis 连接配置是否正确。 ### Q3: 连接 Redis 超时? **A:** 检查 Redis 服务是否启动,防火墙是否开放端口,网络是否连通。 ### Q4: 锁没有自动释放? **A:** 确保 `leaseTime` 设置合理,或者在 finally 块中手动释放(框架已在切面中处理)。 ## License MIT License ## 作者 xiao - 2026/1/9