redis分布式锁在项目中的使用

Redisson分布式锁与Spring Session冲突解决
本文探讨了在使用Redisson实现分布式锁时与Spring Session集成的冲突问题,详细分析了冲突的原因,并提供了有效的解决方案。通过调整Spring Security的配置,确保了Redisson和Spring Session的兼容性。

 

1 pom

        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson-spring-boot-starter</artifactId>
            <version>3.11.5</version>
        </dependency>

 

2 使用

import org.redisson.api.RedissonClient;

    @Resource
    private RedissonClient redissonClient;

加锁

RLock lock = redissonClient.getLock("key");
// 获得锁5s后自动解锁
lock.lockInterruptibly(5L, TimeUnit.SECONDS);
try{
    // 业务代码
}finally {
            try{
                lock.unlock();
            }catch (Exception e){
                log.error("解锁失败", e);
            }
        }

 

 

3 记录一个问题:redis分布式锁与spring-session-data-redis冲突问题分析

security使用redis做session存储

加入redisson后导致redisson的hash slot计算出错:CROSSSLOT Keys in request don't hash to the same slot……

解决:

	
		@EnableRedisHttpSession(redisNamespace = "{spring:session}")

 

    原理:
        1 当mget/mset批量操作时,集群环境下需要Hash Tag:{}包裹主体key值计算,例如:{a:b:c:}111,{a:b:c:}222
        2 当SpringSecurity集成redis做session时,会处理批量操作,所以会出现此错误(猜测)

 

Redis分布式锁可以用于多个进程或者多台机器之间的互斥访问,保证同一时间只有一个进程或者机器能够对某个共享资源进行操作,从而避免数据的冲突和错误。 以下是一个使用Redis分布式锁的示例: 1.首先,在项目中引入Redis相关依赖,例如使用Spring Boot可以在pom.xml文件中加入以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> ``` 2.创建一个RedisLock类,用于封装Redis分布式锁的相关操作: ```java @Component public class RedisLock { @Autowired private RedisTemplate redisTemplate; /** * 获取锁 * @param key 锁的名称 * @param value 锁的值 * @param expireTime 锁的过期时间 * @return */ public boolean lock(String key, String value, long expireTime) { // 尝试加锁 if (redisTemplate.opsForValue().setIfAbsent(key, value)) { // 设置锁的过期时间 redisTemplate.expire(key, expireTime, TimeUnit.MILLISECONDS); return true; } return false; } /** * 释放锁 * @param key 锁的名称 * @param value 锁的值 */ public void unlock(String key, String value) { // 判断当前锁是否属于当前线程持有 if (value.equals(redisTemplate.opsForValue().get(key))) { // 删除锁 redisTemplate.delete(key); } } } ``` 3.在需要使用分布式锁的地方,注入RedisLock类,并调用lock方法进行加锁操作,在操作完成后调用unlock方法释放锁: ```java @Service public class MyService { @Autowired private RedisLock redisLock; public void myMethod(String key) { // 尝试加锁 boolean locked = redisLock.lock(key, "value", 5000); if (locked) { try { // 操作共享资源 // ... } finally { // 释放锁 redisLock.unlock(key, "value"); } } else { // 获取锁失败 // ... } } } ``` 以上就是一个简单的Redis分布式锁使用示例。需要注意的是,在设置锁的过期时间时,需要根据具体业务场景进行调整。同时,为了避免锁持有时间过长导致的问题,建议在finally块中释放锁,以确保锁的释放能够得到保证。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值