基于Redis实现延迟队列消息更新Mysql数据

一、前景信息

      基于像双十一大促销这样的活动,用户参与量极剧增加,当很多用户参与一项活动时,比如抽奖场景,这种场景下,当数据库中有一条记录专门记录库存时,如果是通过锁这一条记录更新库存时,就会出现大量的用户在应用获得数据库的连接后,等待前一个用户更新完库表释放锁,才进入再扣减库存,这样就会有很多用户处于等待状态,而等待的用户是持久数据库连接的,这个资源非常宝贵,占用后,其他请求进不来,最终导致一个请求需要几分钟来响应。所以这种情况一般都是使用redis缓存来处理库存,只要保证没有出现超卖的情况。这里通过 Redisson 延迟队列的 + 定时任务的方式,缓慢消耗队列数据来更新库表数据变化。

二、流程实现

2.1 缓存奖品库存

   public boolean assembleLotteryStrategy(Long strategyId) {
        // 1. 查询策略配置
        List<StrategyAwardEntity> strategyAwardEntities = repository.queryStrategyAwardList(strategyId);

        /* 2 缓存奖品库存   */
        for (StrategyAwardEntity strategyAward : strategyAwardEntities) {
            Integer awardId = strategyAward.getAwardId();
            Integer awardCount = strategyAward.getAwardCount();
            cacheStrategyAwardCount(strategyId, awardId, awardCount);
        }
}

 /**
     * 缓存奖品库存到Redis
     *
     * @param strategyId 策略ID
     * @param awardId    奖品ID
     * @param awardCount 奖品库存
     */
    private void cacheStrategyAwardCount(Long strategyId, Integer awardId, Integer awardCount) {
        String cacheKey = Constants.RedisKey.STRATEGY_AWARD_COUNT_KEY + strategyId + Constants.UNDERLINE + awardId;
        repository.cacheStrategyAwardCount(cacheKey, awardCount);
    }


 public void cacheStrategyAwardCount(String cacheKey, Integer awardCount) {
        if (redisService.isExists(cacheKey)) return;
        redisService.setAtomicLong(cacheKey, awardCount);
    }

 public void setAtomicLong(String key, long value) {
        redissonClient.getAtomicLong(key).set(value);
    }

        在Domain层这里增加了缓存奖品库存数据的操作,最终会调用仓储层,向缓存写入数据。

StrategyRepository中的cacheStrategyAwardCount方法  redissonClient.getAtomicLong(key).set(value);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值