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的时候,锁才会被删除。

相关推荐
欢呼的太阳6 小时前
数据库设计Step by Step (10)——范式化
服务器·数据库·oracle
喜欢的名字被抢了7 小时前
MySQL基础入门:从零理解数据库与SQL
数据库·mysql·教程
Elastic 中国社区官方博客8 小时前
如何比较两个 Elasticsearch 索引并找出缺失的文档
大数据·运维·数据库·elasticsearch·搜索引擎
DLYSB_8 小时前
生命通道:如何用 HIS 医疗系统直连网络声光终端,打造“零延误”的危急值响应网关?
java·网络·数据库·报警灯
儒雅的大叔8 小时前
MySQL数据库InnoDB数据恢复工具使用总结
数据库·mysql·adb
观远数据9 小时前
ChatBI选型对比:从意图识别到SQL修复,六个维度打分决定是否值得投产
数据库·人工智能·sql
嘉&年华9 小时前
【第008篇】通过dexp和dimp命令导出和导入dmp文件(适用于达梦数据库)
数据库·sql
哥是强混10 小时前
Means:基于 .NET 10 打造的开源自部署 S3 兼容对象存储服务
网络·数据库·.net
ffqws_10 小时前
redis面试:如何保证双写一致
数据库·redis·缓存
水无痕simon10 小时前
6 数据库同义词
数据库