业务级分布式锁
版本: v1.0.1
状态: ✅ 已实现
依赖: Redis (ioredis)
📑 目录
概述
monSQLize v1.0.1 引入了业务级分布式锁功能,基于 Redis 实现,用于保护复杂业务逻辑的临界区,防止并发冲突。
核心特性
- ✅ 原子操作:基于 Redis SET NX PX 原子命令
- ✅ 自动释放:支持 TTL 自动过期,防止死锁
- ✅ 重试机制:可配置重试次数和间隔
- ✅ 错误处理:Redis 连接中断检测和降级策略
- ✅ 统计监控:内置锁操作统计信息
- ✅ 与事务配合:可与
withTransaction无缝组合
适用场景
不适用场景
快速开始
1. 安装依赖
2. 配置
3. 使用
API 参考
withLock(key, callback, options?)
自动管理锁生命周期(推荐)。
签名:
参数:
返回值:Promise<T> - callback 的返回值
示例:
acquireLock(key, options?)
手动获取锁(阻塞重试)。
签名:
返回值:Promise<Lock> - Lock 对象
Lock 对象方法:
示例:
tryAcquireLock(key, options?)
尝试获取锁(不阻塞)。
签名:
返回值:Promise<Lock | null> - Lock 对象或 null
示例:
getLockStats()
获取锁统计信息。
签名:
返回值:
示例:
配置选项
全局配置
在 MonSQLize 构造函数中配置:
API 级别配置
在每次调用时可以覆盖默认值:
使用场景
场景1:库存扣减(复杂业务)
场景2:订单创建(锁+事务)
场景3:定时任务防重
场景4:外部API调用
与事务配合
业务锁可以与 monSQLize 事务无缝配合:
为什么锁在外?
- 锁保护整个业务流程(包括事务前的查询和计算)
- 事务保证数据库操作的原子性
- 两者互补,不冲突
错误处理
错误类型
处理示例
降级策略
降级建议:
最佳实践
1. 锁 Key 统一管理
2. 锁粒度选择
3. TTL 设置
4. 错误处理
5. 监控统计
常见问题
Q1: 业务锁 vs 事务锁有什么区别?
Q2: 什么时候需要业务锁?
需要业务锁的场景:
- ✅ 复杂业务(查询→计算→多表更新)
- ✅ 定时任务防重
- ✅ 外部API调用后更新数据库
不需要业务锁的场景:
- ❌ 简单扣减(用事务+条件更新)
- ❌ 防止用户重复点击(用速率限制)
Q3: Redis 不可用怎么办?
Q4: 锁超时了会怎样?
锁会自动释放(TTL机制),不会造成死锁。
Q5: 如何避免死锁?
- ✅ 使用
withLock(自动释放) - ✅ 手动获取锁时使用
try...finally - ✅ 设置合理的 TTL
Q6: 支持锁续期吗?
支持,使用 lock.renew(ttl):
与专业锁库的对比
建议:
- 大部分场景使用 monSQLize 业务锁
- 金融/支付等核心场景使用 Redlock
- 简单场景可考虑其他轻量库