• Redisson的分布式锁的简单实现


    Redisson的分布式锁的简单实现

    更多请参考官网:
    redisson的GitHub:https://github.com/redisson/redisson/wiki
    环境:springboot2.2.5,mybatis,redis,
    1.Maven依赖

         <dependency>
          <groupId>org.redisson</groupId>
          <artifactId>redisson</artifactId>
          <version>3.8.0</version>
        </dependency>
    

    2.Yaml

    server:
      port: 8099
    
    spring:
      datasource:
        url: jdbc:mysql://127.0.0.1:3306/redis_demo?serverTimezone=GMT%2B8
        username: root
        password: 123456
        hikari: # https://github.com/brettwooldridge/HikariCP (uses milliseconds for all time values)
          maximumPoolSize: 10
          minimumIdle: 2
          idleTimeout: 600000
          connectionTimeout: 30000
          maxLifetime: 1800000
      # Redis数据库索引(默认为0)
      redis:
        database: 0
         # Redis服务器地址
        host: 192.168.221.136
        # Redis服务器连接端口
        port: 7000
        # Redis服务器连接密码(默认为空)
        password:
        # 连接池最大连接数(使用负值表示没有限制)
        jedis:
          pool:
            max-active: 200
              # 连接池最大阻塞等待时间(使用负值表示没有限制)
              #        max-wait: -1
              # 连接池中的最大空闲连接
            max-idle: 10
              # 连接池中的最小空闲连接
            min-idle: 0
          # 连接超时时间(毫秒)
        timeout: 10000
    
    ## 该配置节点为独立的节点,有很多同学容易将这个配置放在spring的节点下,导致配置无法被识别
    mybatis:
      mapUnderscoreToCamelCase: true
      typeAliasesPackage: com.ls.pojo
      mapperLocations: classpath:mappers/*.xml
    
    

    3.RedisSonConfig配置类

    @Configuration
    public class RedisSonConfig {
    
        @Value("${spring.redis.host}")
        private String host;
    
        @Value("${spring.redis.port}")
        private String port;
    
        @Value("${spring.redis.password}")
        private String password;
    
        @Bean
        public RedissonClient getRedisson() {
            Config config = new Config();
            config.useSingleServer().setAddress("redis://" + host + ":" + port);
            //config.useSingleServer().setAddress("redis://" + host + ":" + port).setPassword(password);
            //添加主从配置
            //config.useMasterSlaveServers().setMasterAddress("").setPassword("").addSlaveAddress(new String[]{"", ""});
            return Redisson.create(config);
        }
    
    
    }
    
    

    4.主要业务代码及实现

     @Transactional(rollbackFor = Exception.class)
        @Override
        public Boolean killItemV4(Long killId, Integer buyNum) throws Exception {
            Boolean result = false;
            String keyId = String.valueOf(killId);
            final String lockKey = new StringBuffer().append(killId).append("-RedisSonLock").toString();
            RLock lock = redisSonUtils.getRLock(lockKey);
    
            try {
                /**
                 * 第一个参数30s=表示尝试获取分布式锁,并且最大的等待获取锁的时间为30s
                 * 第二个参数10s=表示上锁之后,10s内操作完毕将自动释放锁
                 */
                Boolean cacheRes = lock.tryLock(30, 10, TimeUnit.SECONDS);
                if (cacheRes) {
                    //TODO:核心业务逻辑的处理
                    //先从redis查库存
                    stockNum = (Integer) redisUtil.get(keyId);
                    logger.info("redis库存:" + stockNum);
                    if (stockNum == null) {
                        TbItem dbTbItem = tbItemMapper.selectByPrimaryKey(killId);
                        stockNum = dbTbItem.getNum();
                        redisUtil.set(keyId, stockNum);
                    }
                    if (stockNum <= 0) {
                        throw new Exception("库存不足01!");
                    }
                    if (stockNum >= 0) {
                        //先更新redis库存
                        Long kcNum = redisUtil.decr(keyId, buyNum);
                        logger.info("redis剩余库存:" + kcNum);
                        stockNum -= buyNum;
                        if (kcNum.intValue() != stockNum) {
                            throw new Exception("系统错误!");
                        }
                        TbItem tbItem = new TbItem();
                        tbItem.setId(killId);
                        tbItem.setNum(stockNum);
                        tbItem.setUpdated(new Date());
                        //更新数据库库存
                        int res = tbItemMapper.updateByPrimaryKeySelective(tbItem);
                        if (res > 0 && stockNum >= 0) {
                            logger.info("购买成功");
                            result = true;
                        }
                    }
                }
    
            } finally {
                //TODO:释放锁
                lock.unlock();
            }
            return result;
    
        }
    

    5.测试结果
    redis:
    在这里插入图片描述
    在这里插入图片描述
    开20线程,使用JMeter测试
    在这里插入图片描述
    成功5个,失败15
    在这里插入图片描述
    redis库存
    在这里插入图片描述
    数据库库存
    在这里插入图片描述
    6.更多代码请访问我的github:https://github.com/smileLs66/springboot
    项目名是:redisson
    若发现错误还请各位大佬指正;谢谢
    欢迎兴趣的同学一起交流:qq群:1081601635

  • 相关阅读:
    C++ 动态链接库、静态链接库
    WIN32 PE结构 重定位表
    WIN32 PE Bound Import 绑定导入表
    WIN32申请内存 物理页 VirtualAlloc VirtualFree
    PE文件结构详解 PE导入表
    PE文件结构详解 PE导出表
    WIN PE文件插入MessageBox
    WIN32 创建窗口 WNDCLASS 和CreateWindow
    053464
    053463
  • 原文地址:https://www.cnblogs.com/szls-666/p/12494142.html
Copyright © 2020-2023  润新知