27.Redisson基本使用和可重入性

基于setnx实现分布式锁存在下面问题

1.锁不可重入

同一个线程无法多次获取同一把锁。

2.不可重试

上一篇中实现的分布式锁是非阻塞式的,如果获取锁失败就立刻返回获取锁失败,不会重试获取锁。没有重试机制。

3.锁超时释放

虽然锁超时释放可以避免死锁,但如果是业务本身执行耗时较长,也会导致锁释放,存在安全隐患。

4.主从一致

如果redis是主从集群的,主从同步存在延迟,当主宕机时还没来得及方锁数据同步给从节点,那么其他线程就获取到了锁,造成线程安全问题。

Redisson

Redisson是一个基于redis基础上实现的java驻内存数据网格。

提供了一系列分布式的java常用对象。

提供了许多分布式服务。其中就包括分布式锁。

java 复制代码
<!--redisson-->
<dependency>
   <groupId>org.redisson</groupId>
   <artifactId>redisson</artifactId>
   <version>3.13.6</version>
</dependency>
java 复制代码
package com.xkj.org.config;

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author xiankejin
 * @descrition
 * @date 2025/10/15
 */
@Configuration
public class RedisConfig {

    @Bean
    public RedissonClient redissonClient() {
        Config config = new Config();
        //userSingleServer表示设置单节点,如果有密码设置.setPassword()
        //如果是redis集群地址使用config.useClusterServers()添加集群地址
        config.useSingleServer().setAddress("redis://192.168.19.128:6379");
        //创建redisson客户端对象返回
        return Redisson.create(config);
    }

}
java 复制代码
 /**解决方案:使用redisson */
        // 获取的锁是具有可重入性的,参数是指定锁的名称
        RLock lock = redissonClient.getLock("lock:order:" + userId);
        // 尝试获取锁,
        // 参数1:分别为获取锁的最大等待时间(期间会重试获取锁)可以不传,默认值为-1,表示获取锁失败立即返回,不等待。
        // 参数2,3:锁自动释放时间和单位,不传的情况,默认是30秒。
        // lock.tryLock(); 无参数的方法
//        boolean isLock = lock.tryLock(1, 10, TimeUnit.SECONDS);
        boolean isLock = lock.tryLock();
        if (!isLock) {
            //获取锁失败
            throw new ServiceException("有个用户只允许购买一单,不允许重复下单");
        }
        try {
            //调用Service类自己的方法,使用代理对象,否则事务失效
            //1.需要引入aspectjweaver的依赖
            //2.springboot启动类上添加注解暴露代理对象
            IVoucherOrderService proxy = (IVoucherOrderService) AopContext.currentProxy();
            VoucherOrder voucherOrder = proxy.createVoucherOrder(voucherId, userId);
            //6.返回订单id
            return voucherOrder.getId();
        } finally {
            //释放锁
            lock.unlock();
        }

redisson可重入锁的原理

key为锁名称,value为hash结构分别存入线程标识锁可重入的次数,当可重入次数减为0的时候,锁才会被删除。

相关推荐
Oueii35 分钟前
Django全栈开发入门:构建一个博客系统
jvm·数据库·python
未来龙皇小蓝1 小时前
【MySQL-索引调优】11:Group by相关概念
数据库·mysql·性能优化
2401_831824961 小时前
使用Fabric自动化你的部署流程
jvm·数据库·python
njidf2 小时前
Python日志记录(Logging)最佳实践
jvm·数据库·python
twc8292 小时前
大模型生成 QA Pairs 提升 RAG 应用测试效率的实践
服务器·数据库·人工智能·windows·rag·大模型测试
@我漫长的孤独流浪2 小时前
Python编程核心知识点速览
开发语言·数据库·python
2401_851272992 小时前
实战:用Python分析某电商销售数据
jvm·数据库·python
lay_liu2 小时前
Linux安装redis
linux·运维·redis
枕布响丸辣2 小时前
MySQL 从入门到精通:完整操作手册与实战指南
数据库·mysql
电商API&Tina2 小时前
【电商API接口】开发者一站式电商API接入说明
大数据·数据库·人工智能·云计算·json