Skip to content

Redis 分布式锁使用指南

@DLock 注解(推荐)

基于 DistributedLockAspectConfiguration 切面实现,自动处理锁的获取、释放和异常。

基础示例

java
@Service
public class OrderService {
    
    /**
     * 创建订单
     * 锁 Key: order:create:{orderId}
     */
    @DLock(value = "#orderId", prefix = "order:create", waitTime = 50, leaseTime = 90)
    public void createOrder(String orderId, OrderDTO orderDTO) {
        doCreateOrder(orderId, orderDTO);
    }
    
    /**
     * 扣减库存 - 使用 SpEL 表达式
     * 锁 Key: stock:deduct:{skuId}
     */
    @DLock(value = "#skuId", prefix = "stock:deduct")
    public void deductStock(Long skuId, Integer quantity) {
        doDeductStock(skuId, quantity);
    }
    
    /**
     * 更新用户信息 - 使用对象属性
     * 锁 Key: user:update:{user.id}
     */
    @DLock(value = "#user.id", prefix = "user:update")
    public void updateUser(User user) {
        doUpdateUser(user);
    }
}

参数说明

参数说明默认值
value锁的 Key 值,支持 SpEL 表达式-
prefix锁 Key 的前缀,最终格式为 prefix:value-
waitTime获取锁的最大等待时间(秒)50
leaseTime锁的持有时间(秒),超过后自动释放90

异常处理

获取锁超时时抛出 RuntimeException,提示"请稍后重新重试"。


编程式锁

仅在注解无法满足的动态场景下使用(如锁 Key 运行时动态决定)。

基础示例

java
@Service
public class OrderService {
    
    @Autowired
    private RedisTemplatePrivateWrapper redisWrapper;
    
    public void createOrder(String orderId) {
        // 获取锁(重试 3 秒,锁有效期 10 秒)
        String lockValue = redisWrapper.preemptionKeyLockRetryByAuto(orderId, 10000, 3000);
        
        if (lockValue != null) {
            try {
                doCreateOrder(orderId);
            } finally {
                redisWrapper.releaseSecretKeyLock(orderId, lockValue);
            }
        }
    }
}

常用方法

方法说明
preemptionKeyLockRetryByAuto(lockID, lockMillisecond, retryMillisecond)自动选择加锁策略,返回锁值
preemptionKeyLockRetryByNewSet(lockID, lockMillisecond, retryMillisecond)使用 SET NX EX 策略(Redis 2.6.12+)
preemptionKeyLockRetryBySetNX(lockID, lockMillisecond, retryMillisecond)使用 SETNX + EXPIRE 策略(兼容旧版本)
releaseSecretKeyLock(lockID, lockValue)安全释放锁(验证锁值防止误删)
delayKeyLock(lockID, lockValue, delayMillisecond)延长锁持有时间

获取锁详情信息

java
EnumMap<LockInfoCodeEnum, Object> lockInfo = redisWrapper.preemptionKeyLockRetryByAutoM(
    "order:123", 10000, 3000);

String lockValue = (String) lockInfo.get(LockInfoCodeEnum.LOCK_VALUE);
Long sendTime = (Long) lockInfo.get(LockInfoCodeEnum.LOCK_SEND_TIME);
Long backTime = (Long) lockInfo.get(LockInfoCodeEnum.LOCK_BACK_TIME);

使用建议

场景推荐方式
固定 Key 的同步控制@DLock 注解
动态 Key 的同步控制编程式锁
简单业务方法加锁@DLock 注解
复杂锁逻辑控制编程式锁

Power By 数字海南