关于redis事务

我在做一个秒杀项目,其中活动商品及其库存会放在redis里。
在处理下单的事务方法createOrder中,首先扣减redis里的库存,然后会在数据库里执行一些操作(添加订单,增加销量等)。

//OrderServiceImpl
   @Override
    @Transactional
    public OrderModel createOrder(Integer userId, Integer itemId, Integer promoId, Integer amount, String stockLogId) throws BusinessException {
        //在redis里减库存
        boolean result = itemService.decreaseStock(itemId,amount);
        //在数据库里进行相关操作...
} 

我担心在数据库执行操作时出现异常,导致事务回滚,但redis里的库存就会被白白扣减掉,因此我在redis里减库存操作里添加事务注解:

   @Override
    @Transactional
    public boolean decreaseStock(Integer itemId, Integer amount) throws BusinessException {
        //首先在redis里减库存
        long  result = redisTemplate.opsForValue().increment("promo_item_stock_"+itemId, amount.intValue()*-1);
        if(result > 0){    //更新库存成功
            return true;
        }else if(result == 0) {         //库存已经扣减为0了,此时需要表示库存已经卖完
            redisTemplate.opsForValue().set("promo_item_stock_invalid_"+itemId, "true");
            return true;
        }
        else{
            //到数据库里减
            increaseSales(itemId, amount);
            return false;
        }
    }

但这好像不能保证redis的事务性,如果后续数据库操作出错,redis的库存还是被扣减了。
想问一下该怎么避免这种少卖的情况?

阅读 1.8k
1 个回答

你这个... 我看到你第二段代码里,最后一个 else 的操作不是当 redis 扣库存后库存为负数时,再把库存加回来吗? 这一步不会有数据库的操作啊..

要么你就在 mysql 操作失败后再加回库存,或者,操作失败后发出一个事件,由其它地方来加回库存,或者定时同步数据库和 redis 里的库存..

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题