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 中释放锁,确保锁一定能被释放希望这篇文章能帮你搞定分布式锁面试题和实战项目!如果觉得有用,一键三连是对我最大的支持~

相关推荐
weixin_419658312 小时前
RabbitMQ 应用问题
java·分布式·中间件·rabbitmq
人道领域2 小时前
【Redis实战篇 | Day04】Lua原子性优化Redis分布式锁:解决线程安全问题
java·开发语言·redis·性能优化
希望永不加班2 小时前
SpringBoot 整合 RabbitMQ 入门
java·spring boot·后端·rabbitmq·java-rabbitmq
爱艺江河2 小时前
HarmonyOS智慧风控:基于分布式架构的安全与创新实践
分布式·架构·harmonyos
juniperhan2 小时前
Flink 系列第18篇:Flink 动态表、连续查询与 Changelog 机制
java·大数据·数据仓库·分布式·flink
juniperhan2 小时前
Flink 系列第19篇:深入理解 Flink SQL 的时间语义与时区处理:从原理到实战
java·大数据·数据仓库·分布式·sql·flink
珠海西格电力2 小时前
零碳园区管理系统“云-边-端”架构协同的核心价值
大数据·人工智能·分布式·微服务·架构·能源
我登哥MVP3 小时前
【SpringMVC笔记】 - 12 - 全注解开发
java·spring boot·笔记·spring·tomcat·intellij-idea
阿丰资源3 小时前
基于SpringBoot的高校心理教育辅导系统(附源码+数据库+文档)
数据库·spring boot·后端