• redis分布式锁


    redis在spring 配置

    • jar包引入
            <!--版本号和spring parent版本号一致-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 配置
    package com.itllc.config.RedisConfig;
    
    import org.apache.commons.lang3.StringUtils;
    import org.redisson.Redisson;
    import org.redisson.api.RedissonClient;
    import org.redisson.config.Config;
    import org.redisson.config.SingleServerConfig;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.cache.annotation.EnableCaching;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    
    @Configuration
    @EnableCaching
    public class RedissonConfig {
        @Value("${spring.redis.host}")
        String REDIS_HOST;
    
        @Value("${spring.redis.port}")
        String REDIS_PORT;
    
        @Value("${spring.redis.password}")
        String REDIS_PASSWORD;
    
        @Value("${spring.redis.database}")
        int REDIS_DATABASE;
    
        @Bean
        public RedissonClient redissonClient() {
            Config config = new Config();
            SingleServerConfig r = config.useSingleServer();
            r.setAddress("redis://" + REDIS_HOST + ":" + REDIS_PORT)
                    .setDatabase(REDIS_DATABASE)
                    .setConnectionMinimumIdleSize(5)
                    .setConnectionPoolSize(10);
            if (!StringUtils.isEmpty(REDIS_PASSWORD)) {
                r.setPassword(REDIS_PASSWORD);
            }
            return Redisson.create(config);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    package com.itllc.config.RedisConfig;
    
    import org.apache.commons.lang3.StringUtils;
    import org.redisson.Redisson;
    import org.redisson.api.RedissonClient;
    import org.redisson.config.Config;
    import org.redisson.config.SingleServerConfig;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.cache.annotation.EnableCaching;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    
    @Configuration
    @EnableCaching
    public class RedissonConfig {
        @Value("${spring.redis.host}")
        String REDIS_HOST;
    
        @Value("${spring.redis.port}")
        String REDIS_PORT;
    
        @Value("${spring.redis.password}")
        String REDIS_PASSWORD;
    
        @Value("${spring.redis.database}")
        int REDIS_DATABASE;
    
        @Bean
        public RedissonClient redissonClient() {
            Config config = new Config();
            SingleServerConfig r = config.useSingleServer();
            r.setAddress("redis://" + REDIS_HOST + ":" + REDIS_PORT)
                    .setDatabase(REDIS_DATABASE)
                    .setConnectionMinimumIdleSize(5)
                    .setConnectionPoolSize(10);
            if (!StringUtils.isEmpty(REDIS_PASSWORD)) {
                r.setPassword(REDIS_PASSWORD);
            }
            return Redisson.create(config);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    redis 分布式锁

    package com.itllc.aop;
    
    import lombok.Getter;
    import lombok.Setter;
    import org.redisson.api.RLock;
    
    /**
     * @description 加锁结果类封装了加锁状态和RLock。
     *
     * @author lilinchun
     * @date 2023/06/28
     */
    @Setter
    @Getter
    public class LockResult {
    
        private LockResultStatus lockResultStatus;
    
        private RLock rLock;
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    package com.itllc.aop;
    
    /**
     * @description 加锁结果状态枚举类
     *
     * @author lilinchun
     * @date 2023/06/28
     */
    public enum  LockResultStatus {
    
        /**
         * 通信正常,并且加锁成功
         */
        SUCCESS,
        /**
         * 通信正常,但获取锁失败
         */
        FAILURE,
        /**
         * 通信异常和内部异常,锁状态未知
         */
        EXCEPTION;
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 测试示例
      @GetMapping(value = "/redisLock")
        @ApiOperation("使用redis锁")
        public Result<Boolean> useRedis(@NotBlank @ApiParam(value = "用户信息", required = true) @RequestParam("userId") String userId) {
            return new Result<>(redisService.useRedis(userId));
        }
    // ——————————————————————————————————————————————————————
       @Resource
        private LockManager lockManager;
    
        public Boolean useRedis(String userId) {
            // 锁:userId, 锁超时时间:5s, 锁等待时间:50ms
            LockResult lockResult = lockManager.lock(userId, 5000, 1000);
            try {
                //  业务代码
                System.out.println("执行业务2s!!!!!");
                Thread.sleep(2000);
                System.out.println("执行业务完成!!!!!");
            } catch (Exception e) {
                System.out.println(e.getMessage());
            } finally {
                lockManager.unlock(lockResult.getRLock());
            }
            return true;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 测试工具 Jmeter
      并发同时请求一个参数

    在这里插入图片描述
    在这里插入图片描述
    并发请求不同的参数
    在这里插入图片描述
    在这里插入图片描述
    总结:两次测试结果说明redis的锁生效了,并且有效的解决了分布式事务的问题
    注意:
    解锁方式

      if(lock.isLocked() && lock.isHeldByCurrentThread()){
                    lock.unlock();//解锁
                }
    
    • 1
    • 2
    • 3

    不然会出现问题,自己加的锁自己解锁,还需要判断加锁是否成功了
    问题文章:https://blog.csdn.net/xiyang_1990/article/details/119876496

    使用注解实现redis锁

  • 相关阅读:
    如何查看SSL证书是OV还是DV?
    比Nginx更好用的Gateway!
    好用的Java工具类库—— Hutool
    【AI视野·今日NLP 自然语言处理论文速览 第三十五期】Mon, 18 Sep 2023
    多模态 —— Learnable pooling with Context Gating for video classification
    haas506 2.0开发教程-高级组件库-modem.sms(仅支持2.2以上版本)
    centos下安装JDK环境(离线)
    Linux的进程调度实现
    leetcode(力扣) 491. 递增子序列(回溯 & 去重思路)
    iPhone 如何强制重启
  • 原文地址:https://blog.csdn.net/L1569850979/article/details/131451023