Spring Boot + Redis 实战分布式锁:从入门到精通

一、为什么需要分布式锁?在单机环境下,我们使用 synchronized 或 ReentrantLock 就能轻松解决并发问题。但当应用部署到多节点时,每个节点都有独立的JVM进程,本地锁只能控制单个进程内的线程,无法协调多个进程之间的竞争。举一个典型的场景:用户秒杀活动。假设有10000个用户同时抢购100件商品,如果部署了3台服务器,没有分布式锁的话,可能会有300个请求同时通过库存校验,导致超卖。分布式锁的核心作用:保证在分布式环境下,只有一个进程能获取到资源的访问权。二、Redis实现分布式锁的原理Redis 之所以能实现分布式锁,主要依赖以下特性:SETNX 命令:SET if Not eXists,只有key不存在时才设置成功过期时间:防止锁永久占用,导致死锁唯一value:标识锁的持有者,支持安全释放最简单的实现public String tryLock(String key, String value, long expireTime) {

Boolean success = redisTemplate.opsForValue()

.setIfAbsent(key, value, expireTime, TimeUnit.SECONDS);

return success ? value : null;

}

public void unlock(String key, String value) {

if (value.equals(redisTemplate.opsForValue().get(key))) {

redisTemplate.delete(key);

}

}但这只是最基础版本,存在两个致命问题:问题一:锁过期但任务未完成比如设置锁过期10秒,但实际业务需要15秒。10秒后锁自动释放,另一个线程获取锁开始执行,导致两个线程同时持有锁。问题二:原子性问题先查询再删除不是原子操作,可能查询时锁还在,删除时锁已经被别人获取了。三、Redisson 实战:企业级分布式锁Redisson 是 Redis 的主流客户端,封装了完善的分布式锁实现,我们来直接看代码。引入依赖

org.redisson

redisson-spring-boot-starter

3.25.0

使用分布式锁@Service

@Slf4j

public class OrderService {

复制代码
@Autowired
private RedissonClient redissonClient;

public void createOrder(String productId, int quantity) {
    String lockKey = "order:lock:" + productId;
    RLock lock = redissonClient.getLock(lockKey);
    
    try {
        // 尝试获取锁,等待10秒,锁定30秒后自动释放
        boolean locked = lock.tryLock(10, 30, TimeUnit.SECONDS);
        
        if (!locked) {
            log.warn("获取锁失败,商品{}正在被处理", productId);
            throw new BusinessException("系统繁忙,请稍后重试");
        }
        
        // 业务逻辑:检查库存、扣减库存、创建订单
        Integer stock = getStockFromDB(productId);
        if (stock < quantity) {
            throw new BusinessException("库存不足");
        }
        updateStock(productId, stock - quantity);
        Order order = new Order();
        order.setProductId(productId);
        order.setQuantity(quantity);
        orderRepository.save(order);
        
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        throw new BusinessException("订单处理被中断");
    } finally {
        if (lock.isHeldByCurrentThread()) {
            lock.unlock();
        }
    }
}

}Redisson 的三大优势Watch Dog 自动续期:默认每10秒检查一次,如果锁还在持有就自动延长30秒可重入:同一线程可多次获取同一把锁公平锁/读写锁:支持更复杂的锁场景四、常见问题与解决方案Q1: Redis 主从切换导致锁丢失?问题:如果Master宕机,Replication未完成,锁就丢了。解决方案:使用 RedLock 算法,同时在N个独立的Redis实例上获取锁。Q2: 如何选择分布式锁的实现?方案优点缺点Redis SETNX性能高,实现简单需要处理过期、续期Redisson功能完善,开箱即用依赖较重ZooKeeper一致性最强性能较低对于大多数场景,Redisson 是最佳选择。五、总结分布式锁是解决分布式环境下资源竞争的核心手段Redis SETNX 是实现分布式锁的基石生产环境推荐使用 Redisson,它解决了锁超时、原子性、可重入等核心问题使用时注意:在 finally 中释放锁,确保锁一定能被释放希望这篇文章能帮你搞定分布式锁面试题和实战项目!如果觉得有用,一键三连是对我最大的支持~

相关推荐
摇滚侠7 小时前
SpringBoot 面试题 真正的 offer 偏方 Java 基础 Java 高级
java·spring boot·后端
敖正炀8 小时前
读写分离与数据库中间件选型
分布式
升鲜宝供应链及收银系统源代码服务9 小时前
升鲜宝生鲜配送供应链系统 vs_车辆管理模块开发文档 PRD(一)---升鲜宝生鲜配送供应链管理系统
spring boot·java-ee·生鲜供应链源代码·供应链源代码出售·生鲜配送源代码服务·门店连锁系统源代码·猪肉生产加工系统源代码
Mahir089 小时前
Redis 分布式锁与 Redisson 深度解析:从原生实现到工业级解决方案
数据库·redis·分布式·缓存·面试
敖正炀9 小时前
分布式事务监控与手动恢复平台设计
分布式
yoyo_zzm9 小时前
六大编程语言核心差异全解析
c语言·c++·spring boot·php
逆境不可逃9 小时前
Hello-Agents 第二部分-第四章总结:智能体经典范式构建-包含习题解析和Java版
java·开发语言·javascript·人工智能·分布式·agent
看我干嘛!9 小时前
Redis安装
数据库·redis·缓存
heimeiyingwang9 小时前
【架构实战】RocketMQ实战:分布式消息中间件
分布式·架构·rocketmq
报错小能手9 小时前
分布式讲解—分布式事务解决方案 刚性(2PC、3PC、XA协议)
分布式