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

相关推荐
马克学长3 小时前
SSM桐梓娄山书店管理系统6k3s6(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面
数据库·用户管理·ssm框架·书店管理系统
老华带你飞3 小时前
博物馆展览门户|基于Java博物馆展览门户系统(源码+数据库+文档)
java·开发语言·数据库·vue.js·spring boot·后端
傻啦嘿哟4 小时前
Python安全实践:使用加密的XML配置文件保护敏感数据
数据库·oracle
一 乐4 小时前
人事管理系统|基于Springboot+vue的企业人力资源管理系统设计与实现(源码+数据库+文档)
java·前端·javascript·数据库·vue.js·spring boot·后端
SelectDB4 小时前
浙江头部城商行:每日 700 万查询、秒级响应,Apache Doris 查算分离架构破局资源冲突
数据库·后端·apache
猫猫虫。4 小时前
解决数据库慢查询
数据库
zyxqyy&∞4 小时前
mysql代码小练-3
数据库·mysql
dzl843944 小时前
HikariCP 数据库连接池配置
数据库
万邦科技Lafite4 小时前
一键获取淘宝关键词商品信息指南
开发语言·数据库·python·商品信息·开放api·电商开放平台
程序猿20235 小时前
MySQL的索引
数据库·mysql