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

相关推荐
IronMurphy10 小时前
【算法五十七】146. LRU 缓存
算法·缓存
茉莉玫瑰花茶10 小时前
综合案例 - AI 智能租房助手 [ 5 ]
服务器·数据库·人工智能·python·ai
ywl47081208710 小时前
jwt生产token,简单版helloworld
java·数据库·spring
器灵科技11 小时前
AI视频工具实测:Seedance/可灵/HappyHorse谁最能打?
java·运维·数据库·人工智能·github
huangdong_11 小时前
京东商品图片视频批量下载与m3u8视频合并技术完整实现方案
大数据·前端·数据库
倒流时光三十年11 小时前
PostgreSQL CASE 条件表达式详解
数据库·postgresql
字节跳动数据平台12 小时前
营销视频进入工业化时代,火山引擎多模态数据湖如何助力多米实现内容生产提效 100+ 倍
数据库
健康平安的活着12 小时前
mysql中数据库脚本太大,通过脚本命令修改db名称
数据库·mysql
伊甸312 小时前
从企业级项目学敏感词过滤:DFA算法与双层缓存实战
java·算法·缓存
倒流时光三十年12 小时前
PostgreSQL COALESCE 条件表达式函数详解
数据库·postgresql