pig Cloud中分布式锁的使用(setIfAbsent)
分布式锁实现解析(仅供参考-基本使用是够的)
特性 | 本代码实现方式 |
---|---|
互斥性 | 使用 setIfAbsent (SETNX 命令)保证 |
防死锁 | 通过设置过期时间(lockTimeout )保证 |
释放锁的安全性 | 通过校验 lockValue 防止误删 |
锁的自动续期 | ❌ 未实现 |
集群容错 | ❌ 单节点模式,无容错 |
1. 锁核心机制
String lockValue = UUID.randomUUID().toString();
String lockKey = TaskLockKeyEnum.SAVE_MONTH_HOURS_EXCEL.getKey();
long lockTimeout = saveExcelConfig.getLockTimeout();// 1. 获取锁(SETNX + 过期时间)
if (redisTemplate.opsForValue().setIfAbsent(lockKey, lockValue, lockTimeout, TimeUnit.MINUTES)) {try {// 2. 执行业务逻辑jjbHandoverLogService.uploadMonthHoursExcel(yearMonth);} finally {// 3. 释放锁(先校验值再删除)if (lockValue.equals(redisTemplate.opsForValue().get(lockKey))) {redisTemplate.delete(lockKey);}}
}
- 原子性操作:
setIfAbsent
实现原子性操作(等价于 Redis 的SET key value NX PX
命令) - 锁标识:使用
UUID
生成唯一值,避免不同节点冲突 - 超时机制:通过
lockTimeout
设置自动过期时间(单位:分钟),防止死锁 - 键管理:枚举
TaskLockKeyEnum
统一管理锁键名
2. 锁释放逻辑
finally {
// 释放锁,确保即使任务执行异常也能释放锁if (lockValue.equals(redisTemplate.opsForValue().get(lockKey))) {redisTemplate.delete(lockKey);}
}
- 值校验释放:比较当前锁值是否与初始值一致
- 防误删设计:确保只释放当前节点持有的锁
- finally 保障:异常情况下仍执行释放操作
典型应用场景:集群环境下定时任务的精确调度,如报表生成、数据归档等需要全局唯一执行的操作。
分布式锁实现解析
1. 锁核心机制
String lockValue = UUID.randomUUID().toString();
String lockKey = TaskLockKeyEnum.SAVE_MONTH_HOURS_EXCEL.getKey();
long lockTimeout = saveExcelConfig.getLockTimeout();if (redisTemplate.opsForValue().setIfAbsent(lockKey, lockValue, lockTimeout, TimeUnit.MINUTES)) {// 获取锁成功
} else {// 获取锁失败
}
- 原子性操作:
setIfAbsent
实现原子性操作(等价于 Redis 的SET key value NX PX
命令) - 锁标识:使用
UUID
生成唯一值,避免不同节点冲突 - 超时机制:通过
lockTimeout
设置自动过期时间(单位:分钟),防止死锁 - 键管理:枚举
TaskLockKeyEnum
统一管理锁键名
2. 锁释放逻辑
finally {if (lockValue.equals(redisTemplate.opsForValue().get(lockKey))) {redisTemplate.delete(lockKey);}
}
- 值校验释放:比较当前锁值是否与初始值一致
- 防误删设计:确保只释放当前节点持有的锁
- finally 保障:异常情况下仍执行释放操作
3. 任务执行流程
graph TD
A[定时任务触发] --> B{获取分布式锁}
B -- 成功 --> C[检查任务开关]
B -- 失败 --> D[记录跳过日志]
C -- 开启 --> E[执行Excel导出]
E --> F[释放锁]
C -- 关闭 --> G[结束]
4. 关键特性
配置驱动
# 示例配置 saveExcel.lockTimeout=30 # 锁超时30分钟
典型应用场景:集群环境下定时任务的精确调度,如报表生成、数据归档等需要全局唯一执行的操作。