SpringBoot分布式Redis锁Redisson

原理

流程分析:

  1. 尝试获取锁,返回 null 则说明加锁成功,返回一个数值,则说明已经存在该锁,ttl 为锁的剩余存活时间。
  2. 如果此时客户端 2 进程获取锁失败,那么使用客户端 2 的线程 id(其实本质上就是进程 id)通过 Redis 的 channel
    订阅锁释放的事件。如果等待的过程中一直未等到锁的释放事件通知,当超过最大等待时间则获取锁失败,返回 false。如果等到了锁的释放事件的通知,则开始进入一个不断重试获取锁的循环。
  3. 循环中每次都先试着获取锁,并得到已存在的锁的剩余存活时间。如果在重试中拿到了锁,则直接返回。如果锁当前还是被占用的,那么等待释放锁的消息,具体实现使用了JDK 的信号量 Semaphore 来阻塞线程,当锁释放并发布释放锁的消息后,信号量的 release()方法会被调用,此时被信号量阻塞的等待队列中的一个线程就可以继续尝试获取锁了。

特别注意:以上过程存在一个细节,这里有必要说明一下,也是分布式锁的一个关键点:当锁正在被占用时,等待获取锁的进程并不是通过一个 while(true) 死循环去获取锁,而是利用了 Redis 的发布订阅机制,通过 await 方法阻塞等待锁的进程,有效的解决了无效的锁申请浪费资源的问题。

代码

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson-spring-boot-starter</artifactId>
    <version>3.16.4</version>
</dependency>
@Configuration
public class RedissonConfig {

    @Value("${redisson.address}")
    private String address;//redis://xxx.x.x.x:6379
    @Value("${redisson.password}")
    private String password;
    
    //单例模式
    @Bean
    public RedissonClient redissonClient() {
        Config config = new Config();
        config.useSingleServer()
                .setAddress(address)
                .setPassword(password);
        return Redisson.create(config);
    }
}
	//1.获取锁
	RLock lock = redissonClient.getLock("xxxx");
	// 2.加锁
    lock.lock();
    try {
    	//业务代码
	} finally {
    	//3.解锁
    	lock.unlock();
	}

注意

加锁解锁尽量放到方法头尾,防止遗漏校验.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Spring Boot整合RedisRedisson可以让我们更方便地使用Redis作为缓存或分布式。下面是一个简单的示例,展示了如何在Spring Boot项目中实现这个整合: 1. 首先,在pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.redisson</groupId> <artifactId>redisson-spring-boot-starter</artifactId> <version>3.16.0</version> </dependency> ``` 2. 在application.properties或application.yml中配置Redis连接信息: ```properties spring.redis.host=127.0.0.1 spring.redis.port=6379 ``` 3. 在你的Spring Boot配置类中添加Redisson的配置: ```java @Configuration public class RedissonConfig { @Bean public RedissonClient redissonClient() { Config config = new Config(); config.useSingleServer() .setAddress("redis://127.0.0.1:6379"); return Redisson.create(config); } } ``` 4. 在你的业务代码中使用RedisRedisson: ```java @Service public class MyService { @Autowired private RedisTemplate<String, Object> redisTemplate; @Autowired private RedissonClient redissonClient; public void put(String key, Object value) { // 使用RedisTemplate操作Redis redisTemplate.opsForValue().set(key, value); // 使用Redisson操作Redis RMap<String, Object> map = redissonClient.getMap("myMap"); map.put(key, value); } public Object get(String key) { // 使用RedisTemplate操作Redis return redisTemplate.opsForValue().get(key); // 使用Redisson操作Redis RMap<String, Object> map = redissonClient.getMap("myMap"); return map.get(key); } } ``` 通过上述步骤,你就成功地将RedisRedisson整合到了你的Spring Boot项目中。可以使用`redisTemplate`来直接操作Redis,也可以使用`redissonClient`来获得更多Redisson提供的功能,例如分布式分布式集合等。希望对你有帮助!如果还有其他问题,请继续提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

之一丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值