在上面的文章中,我们实现了异步扣库存,但是还是存在问题。
1.超卖问题的解决
在原来单体架构的过程中,我们可以使用redis锁,实现超卖问题的解决
@Override
public Integer decreaseStock(List<OrderItem> orderItemList) {
/**
* 加锁
*/
int count = 0;
for (OrderItem orderItem: orderItemList) {
/**
* 加锁
*/
long time = System.currentTimeMillis() + TIMEOUT;
if(!redisLock.lock(orderItem.getGoodsId().toString(), String.valueOf(time))){
throw new LovingMallException(ExceptionCodeEnum.SYSTEM_BUSY);
}
GoodsInfo goodsInfo = goodsInfoMapper.selectByPrimaryKey(orderItem.getGoodsId());
if(goodsInfo == null){
throw new LovingMallException(ExceptionCodeEnum.PRODUCT_NOT_EXIT);
}
Integer resultStock = goodsInfo.getStockNum() - orderItem.getGoodsCount();
if(resultStock < 0){
throw new LovingMallException(ExceptionCodeEnum.STOCK_WARN);
}
goodsInfo.setStockNum(resultStock);
count += goodsInfoMapper.updateByPrimaryKeySelective(goodsInfo);
/**
* 解锁
*/
redisLock.unlock(orderItem.getGoodsId().toString(),String.valueOf(time));
}
return count;
}
// 6.扣库存
count = goodsInfoService.decreaseStock(orderDTO.getOrderItemList());
if(count > 0){
return ServerResponse.createBySuccessMessage("下单成功");
}else {
throw new LovingMallException(ExceptionCodeEnum.STOCK_WARN);
}
现在微服务架构下,redis锁,已经不再适合,因为消费者(product)
消费消息(message)
的时间是不确定的。
推荐方法:
网友评论