- 生产者完成创建订单和扣减库存之后,发送消息到延迟队列。
java
// 3.清理购物车商品
cartClient.deleteCartItemByIds(itemIds);
// cartService.removeByItemIds(itemIds);
// 4.扣减库存
try {
itemClient.deductStock(detailDTOS);
//itemService.deductStock(detailDTOS);
} catch (Exception e) {
throw new RuntimeException("库存不足!");
}
// 5.TODO发送延迟消息,检查用户是否已经支付完成
rabbitTemplate.convertAndSend(MQConstants.DELAY_EXCHANGE_NAME,
MQConstants.DELAY_ORDER_KEY,
order.getId(),
message -> {
message.getMessageProperties().setDelay(10000);
return message;
});
- 消费者监听消息,先查订单状态,没支付在查支付信息。
java
@Slf4j
@Component
@AllArgsConstructor
public class OrderDelayMessageListener {
private final IOrderService orderService;
private final PayClient payClient;
@RabbitListener(bindings = @QueueBinding(
value = @Queue(name = MQConstants.DELAY_ORDER_QUEUE_NAME),
exchange = @Exchange(name = MQConstants.DELAY_EXCHANGE_NAME, delayed = "true"),
key = MQConstants.DELAY_ORDER_KEY
))
public void listenOrderDelayMessage(Long orderId) {
// 1.查询订单状态
Order order = orderService.getById(orderId);
// 2.检测订单状态,判断是否已支付
if(order == null || order.getStatus()!=1) {
log.info("delayMQ:用户已支付订单【{}】",orderId);
return;
}
// 3.未支付,查询订单流水
PayOrderDTO payOrder = payClient.queryPayOrderByBizOrderNo(orderId);
// 4.判断是否支付
if (payOrder == null || payOrder.getStatus() == 3) {
// 4.1 已支付,标记订单状态已支付
orderService.markOrderPaySuccess(orderId);
log.info("delayMQ:已更新订单【{}】",orderId);
} else {
// 4.2 未支付,取消订单,恢复库存
orderService.cancelOrder(orderId);
log.info("delayMQ:已取消订单【{}】",orderId);
}
}
}