rabbitMQ实现订单超时未支付自动取消订单

这篇具有很好参考价值的文章主要介绍了rabbitMQ实现订单超时未支付自动取消订单。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前期准备

下面展示一些 内联代码片文章来源地址https://www.toymoban.com/news/detail-615915.html

1.配置文件,导入jar包

server:
  port: 8983
spring:
  application:
    name: API-RABBITMQ

  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/yingxue?characterEncoding=UTF-8&useSSL=false
    username: root
    password: 123

  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest
    virtual-host: /

mybatis:
  #mapper配置文件的位置
  mapper-locations: classpath:com.hou.mapper/*.xml
  #别名
  type-aliases-package: com.hou.entity


# 自定义过期时间
order:
  delay:
    time: 12000 # 单位毫秒

2. 使用rabbitMQ插件绑定延时队列,插件可自动实现死信队列,无需配置

//**
 * mq 配置类
 */
@Configuration
public class RabbitMQConfig {

    //声明1个路由key 1个队列 1个交换机
    //延迟交换机
    public static final String DELAY_EXCHANGE_NAME = "delay.exchange";
    //延迟队列
    public static final String DELAY_QUEUE_NAME = "delay.queue";
    //延迟队列路由key
    public static final String DELAY_QUEUE_ROUTING_KEY = "delay.queue.routingkey";

    // 声明延迟交换机,由插件处理代码
    @Bean("delayExchange")
    public CustomExchange delayExchange() {
        HashMap<String, Object> args = new HashMap<>();
        args.put("x-delayed-type", "direct");
        // 自定义的交换机
        return new CustomExchange(DELAY_EXCHANGE_NAME,
                "d-delayed-message", true, false, args);
    }

    // 声明延迟队列,
    @Bean("delayQueue")
    public Queue delayQueueA() {
        return new Queue(DELAY_QUEUE_NAME);
    }

    // 声明延迟队列B的绑定关系
    @Bean
    public Binding delayBindingB(@Qualifier("delayQueue") Queue queue,
                                 @Qualifier("delayExchange") CustomExchange exchange) {
        return BindingBuilder.bind(queue)
                .to(exchange)
                .with(DELAY_QUEUE_ROUTING_KEY)
                .noargs();
    }

}

3. 生产者代码实现,

/**
 * 生产者代码
 */
@Component
public class DelayMessageProducer {

    @Resource
    private RabbitTemplate rabbitTemplate;

    public void send(String message, Integer delayTime) {

        // 三个参数
        rabbitTemplate.convertAndSend(RabbitMQConfig.DELAY_EXCHANGE_NAME,
                RabbitMQConfig.DELAY_QUEUE_ROUTING_KEY,
                message1 -> {
                    message1.getMessageProperties().setDelay(delayTime);
                    return message1;
                });
    }

}

4. service层代码, 创建订单时,同步发送消息到mq,指定超时时间

public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderMapper orderMapper;
    @Autowired  // 注入生产者
    private DelayMessageProducer producer;
    @Value("${order.delay.time}")
    private Integer orderDelayTime;

    /**
     * 保存新增订单
     */
    @Override
    @Transactional
    public Map<String, Object> save(Order order) {

        // 订单编号
        order.setOrderSn(IdUtil.getSnowflake(1, 1).nextIdStr());
        // 订单状态
        order.setOrderStatus(OrderStatus.no_confirm.getStatus());
        // 支付状态
        order.setPayStatus(PayStatus.no_pay.getStatus());
        // 下单时间
        order.setOrderTime(new Date());
        // 使用plus插入一条记录
        int result = orderMapper.insert(order);
        HashMap<String, Object> map = new HashMap<>();

        // 插入成功
        if (result > 0) {
            map.put("code", 200);
            map.put("message", "订单已提交");
            map.put("data", order);
            // 发送消息到延迟队列, 设置消息过期时间
            producer.send(order.getOrderSn(), orderDelayTime);
            return map;
        } else {
            map.put("code", 400);
            map.put("message", "订单提交失败");
            map.put("data", null);
            return map;
        }
    }

5.消费者代码实现,修改订单的状态, 保存未支付订单表中数据

/**
 * 消息消费者
 */
@Slf4j
@Component
public class DeadLetterQueueConsumer {

    @Resource
    private OrderMapper orderMapper;
    @Resource
    private OrderActionMapper orderActionMapper;

    // 监听延迟队列A
    @RabbitListener(queues = RabbitMQConfig.DELAY_QUEUE_NAME)
    public void receiveA(Message message, Channel channel) {
        String orderSn = new String(message.getBody());
        log.info("当前时间: {},  延迟队列收到订单编号: {}", LocalDateTime.now(), orderSn);

        // 根据订单编号查询订单
        QueryWrapper<Order> wrapper = new QueryWrapper<>();
        wrapper.ge("orderSn", orderSn);
        Order order = orderMapper.selectOne(wrapper);

        if (order != null && order.getOrderStatus().equals(OrderStatus.no_confirm.getStatus())
                && order.getPayStatus().equals(PayStatus.no_pay.getStatus())) {
            // 设置订单的状态为已取消
            order.setOrderStatus(OrderStatus.cancel.getStatus());
            // 修改状态
            int result = orderMapper.updateById(order);
            if (result > 0) {
                // 订单取消表中插入数据
                OrderAction orderAction = new OrderAction();
                orderAction.setOrderSn(orderSn);
                orderAction.setOrderStatus(OrderStatus.cancel.getStatus());
                orderAction.setPayStatus(PayStatus.no_pay.getStatus());
                orderAction.setActionNote("支付超时,订单已取消");
                orderAction.setActionTime(new Date());
                orderAction.setStatusDesc("支付超时,订单已取消");
                //新增取消订单 表
                orderActionMapper.insert(orderAction);
            }
        }
    }

}

到了这里,关于rabbitMQ实现订单超时未支付自动取消订单的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 生成订单30分钟未支付,则自动取消,该怎么实现?

    今天给大家上一盘硬菜,并且是支付中非常重要的一个技术解决方案,有这块业务的同学注意自己试一把了哈! 在开发中,往往会遇到一些关于延时任务的需求。例如 生成订单30分钟未支付,则自动取消 生成订单60秒后,给用户发短信 对上述的任务,我们给一个专业的名字来

    2024年02月09日
    浏览(45)
  • 使用RabbitMQ死信队列关闭未支付的订单

    RabbitMQ死信队列(Dead-Letter Exchange,简称DLX)是一种特殊类型的交换机,用于处理在队列中无法被消费的消息。当消息无法被消费时,它会被转发到死信队列中,以便进一步处理。 在RabbitMQ中,死信队列通常用于处理以下情况: 消息无法被消费者处理:例如,如果消费者崩溃

    2024年02月11日
    浏览(38)
  • 订单自动取消的11种实现方式(下)

    在Redis中,有个发布订阅的机制 生产者在消息发送时需要到指定发送到哪个channel上,消费者订阅这个channel就能获取到消息。图中channel理解成MQ中的topic。 并且在Redis中,有很多默认的channel,只不过向这些channel发送消息的生产者不是我们写的代码,而是Redis本身。这里面就有

    2024年02月13日
    浏览(32)
  • 简单的RabbitMQ集成Springboot实现订单异步发送功能示例以及RabbitMQ的相关问题

    引入RabbitMQ的依赖,在pom.xml文件中添加以下代码: 在application.properties文件中配置RabbitMQ的相关信息: 创建消息队列,并定义消息接收者: 定义消息发送者: 在需要发送订单信息的地方调用OrderSender的send方法即可: RabbitMQ是一个开源的消息中间件,主要用于实现应用之间的异

    2024年02月09日
    浏览(39)
  • 商城系统中30分钟未付款自动取消订单怎么实现(简单几种方法)

    实现以上功能 写一个定时任务,每隔 30分钟执行一次,列出所有超出时间范围得订单id的列表 批量执行取消订单操作 实现一个简单的队列,每隔一定时间执行队列。 这里使用队列的优势可以跟前端时间匹配上,前端读秒几秒这里就什么时候取消  使用mq队列,消费消息。如

    2024年01月24日
    浏览(35)
  • Spring Boot中实现订单30分钟自动取消的策略

    🎉欢迎来到架构设计专栏~Spring Boot中实现订单30分钟自动取消的策略 ☆* o(≧▽≦)o *☆嗨~我是IT·陈寒🍹 ✨博客主页:IT·陈寒的博客 🎈该系列文章专栏:架构设计 📜其他专栏:Java学习路线 Java面试技巧 Java实战项目 AIGC人工智能 数据结构学习 🍹文章作者技术和水平有限,

    2024年02月08日
    浏览(58)
  • 设置RabbitMQ超时时间

    RabbitMQ默认的超时时间是30分钟,在消息消费超过30分钟后,rabbitMQ会发生错误,导致整个channel被销毁,无法继续消费 在RabbitMQ安装的终端执行 命令,将超时时间延长。 使用 可以查看设置的超时值。 值得注意的是,这个事临时更改,永久更改需要进入 rabbitmq.con f 文件里修改

    2024年02月04日
    浏览(41)
  • Springboot与RabbitMQ消息超时时间、队列消息超时时间

    TTL是 Time-To-Live 的缩写,RabbitMQ可以对消息和队列设置TTL(过期时间)。 RabbitMQ针对队列中的消息过期时间(Time To Live, TTL)有两种方法可以设置。 第一种方法是通过队列属性设置,队列中所有消息都有相同的过期时间。 第二种方法是对消息进行单独设置,每条消息TTL可以不同。

    2024年02月09日
    浏览(48)
  • Spring Boot整合Redis实现订单超时处理

    🎉欢迎来到架构设计专栏~Spring Boot整合Redis实现订单超时处理 ☆* o(≧▽≦)o *☆嗨~我是IT·陈寒🍹 ✨博客主页:IT·陈寒的博客 🎈该系列文章专栏:架构设计 📜其他专栏:Java学习路线 Java面试技巧 Java实战项目 AIGC人工智能 数据结构学习 🍹文章作者技术和水平有限,如果文

    2024年02月03日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包