关于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的库存还是被扣减了。
想问一下该怎么避免这种少卖的情况?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你这个... 我看到你第二段代码里,最后一个 else 的操作不是当 redis 扣库存后库存为负数时,再把库存加回来吗? 这一步不会有数据库的操作啊..
要么你就在 mysql 操作失败后再加回库存,或者,操作失败后发出一个事件,由其它地方来加回库存,或者定时同步数据库和 redis 里的库存..