关于redis事务

发布于 2022-09-12 04:17:21 字数 1280 浏览 41 评论 0

我在做一个秒杀项目,其中活动商品及其库存会放在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的库存还是被扣减了。
想问一下该怎么避免这种少卖的情况?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

顾忌 2022-09-19 04:17:21

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

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文