Node 定时任务、排他锁、RabbitMQ 实现过期订单自动更新

1、为什么要使用定时任务

  • 当用户下单了,如果长期没付款。将来再去付款的时候,支付宝和微信那边就会提示订单过期了,无法支付。这就是说,订单支付超时后,最好将订单的状态设置为已过期,让用户无法再发起支付。
  • 当用户支付了订单,就会自动变成大会员身份。但是大会员身份是有有效期的,在过期后,就需要将这些用户变成普通用户。

2、node-schedule的使用

2.1、 安装 node-schedule

npm install node-schedule

2.2、 定时代码解析

在这里插入图片描述

*    *    *    *    *    *
┬    ┬    ┬    ┬    ┬    ┬
│    │    │    │    │    │
│    │    │    │    │    └ 星期几 (0 - 7) (07 是星期天)
│    │    │    │    └───── 月份 (1 - 12)
│    │    │    └────────── 日期 (1 - 31)
│    │    └─────────────── 小时 (0 - 23)
│    └──────────────────── 分钟 (0 - 59)
└─────────────────────────  (0 - 59, 可选)

例一:在文档例子里

const job = schedule.scheduleJob('42 * * * *', function(){
   
   
  console.log('The answer to life, the universe, and everything!');
});

大家先数一数,这里只有 5 位数,而完整的格式是 6 位数。这就说明,秒被省略了。那么这个42就是分钟了。这就是说,每个小时的第 42 分钟,会执行一次

例二,下面还有个例子:

const job = schedule.scheduleJob('0 17 ? * 0,4-6', function(){
   
   
  console.log('Today is recognized by Rebecca Black!');
});
  • 0:表示在第 0 分钟时触发。
  • 17:是说在 17 点(也就是下午 5 点)触发。
  • ?:表示不指定具体的日期,因为在最后面一位,指定了星期几。
  • *:表示每个月都运行。
  • 0,4-6:最后面的这个,0 表示:星期天(0)。4-6 表示:星期四(4)、星期五(5)、和星期六(6)都可以。

3.4. 在 Node 项目中使用 node-schedule

// 定时任务
const schedule = require('node-schedule');
const job = schedule.scheduleJob('* * * * * *', function(){
   
   
  console.log('Hello xw!');
});

3、 项目中封装订单的处理

因为一个项目可能有多个定时任务,所以我们可以专门建一个文件夹,来存放定时任务相关的文件

3.1、在根目录中,新建tasks目录,里面再新建一个check-order.js文件。

const schedule = require('node-schedule');
const {
   
    sequelize, Order } = require('../models');
const {
   
    Op } = require('sequelize');
const logger = require('../utils/logger');
const moment = require('moment');

/**
 * 定时检查并处理超时未支付订单
 * 每天凌晨 4:30 执行一次 测试时可改为0 * * * * *  每分钟的第 0 秒
 */
function scheduleOrderCheck() {
   
   
  schedule.scheduleJob('0 30 4 * * *', async () => {
   
   
    const t = await sequelize.transaction();

    try {
   
   
      // 查找超时未支付的订单
      const expiredOrders = await Order.findAll({
   
   
        attributes: ['id'],
        where: {
   
   
          status: 0,
          createdAt: {
   
   
            [Op.lt]: moment().subtract(1, 'day').toDate()
          }
        },
        transaction: t,
        lock: true  // 使用排它锁,防止并发更新
      });

      // 已超时订单的 ID 列表
      const orderIds = expiredOrders.map(order 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值