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

相关推荐
傻啦嘿哟1 天前
Python自动整理音乐文件:按艺术家和专辑分类歌曲
数据库·python·分类
哈里谢顿1 天前
MySQL 和 Redis搭配使用指南
redis·mysql
酸菜牛肉汤面1 天前
16、事物的四大特性(ACID)介绍一下?
数据库·oracle
程序帝国1 天前
SpringBoot整合RediSearch(完整,详细,连接池版本)
java·spring boot·redis·后端·redisearch
FourAu1 天前
更改mysql在电脑中的存储位置
数据库·mysql
哈里谢顿1 天前
通过lua实现redis 分布式锁
redis
AI题库1 天前
PostgreSQL 18 从新手到大师:实战指南 - 2.4 备份与恢复策略
数据库·postgresql·oracle·数据库备份
晴天¥1 天前
Oracle中的概要文件
运维·数据库·oracle
一 乐1 天前
健康管理|基于springboot + vue健康管理系统(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·后端·学习
学编程就要猛1 天前
MySQL:CRUD
数据库·sql·mysql