SpringBoot 实现订单30分钟自动取消的策略
简介
在电商和其他涉及到在线支付的应用中,通常需要实现一个功能:如果用户在生成订单后的一定时间内未完成支付,系统将自动取消该订单。
本文将详细介绍基于Spring Boot框架实现订单30分钟内未支付自动取消的几种方案,并提供实例代码。
方案一:定时任务
利用Spring Boot中的@Scheduled注解,我们可以轻松地实现定时任务。该任务将周期性地扫描数据库,检查未支付的订单,如果订单生成30分钟未支付,则自动取消。
@Component
public class OrderCancelSchedule {@Autowiredprivate OrderService orderService;@Scheduled(cron = "0 0/1 * * * ?")public void cancelUnpaidOrders() {List<Order> unpaidOrders = orderService.getUnpaidOrders();unpaidOrders.forEach(order -> {if (order.getCreationTime().plusMinutes(30).isBefore(LocalDateTime.now())) {orderService.cancelOrder(order.getId());}});}
}
方案二:延迟队列
使用消息队列(如RabbitMQ)的延迟队列功能,当订单生成时将订单ID推送到延迟队列,设置30分钟后过期,过期后消费该消息,取消订单。
@Service
public class OrderService {@Autowiredprivate RabbitTemplate rabbitTemplate;public void createOrder(Order order) {// 保存订单至数据库saveOrderToDB(order);// 将订单ID推送至延迟队列rabbitTemplate.convertAndSend("orderDelayExchange", "orderDelayKey", order.getId(), message -> {message.getMessageProperties().setDelay(30 * 60 * 1000); // 设置延迟时间return message;});}
}@Component
@RabbitListener(queues = "orderDelayQueue")
public class OrderDelayConsumer {@Autowiredprivate OrderService orderService;@RabbitHandlerpublic void process(String orderId) {// 取消订单orderService.cancelOrder(orderId);}
}
方案三:Redis过期事件
利用Redis的键过期事件功能,当订单生成时在Redis中存储一个键,设置30分钟过期,键过期时通过Redis的过期事件通知功能触发订单取消操作。
@Service
public class OrderService {@Autowiredprivate StringRedisTemplate redisTemplate;public void createOrder(Order order) {// 保存订单至数据库saveOrderToDB(order);// 在Redis中存储一个键,设置30分钟过期redisTemplate.opsForValue().set("order:" + order.getId(), order.getId(), 30, TimeUnit.MINUTES);}// 当键过期时,Redis会自动调用该方法(需要配置Redis的过期事件通知功能)public void onOrderKeyExpired(String orderId) {cancelOrder(orderId);}
}
补充一下配置Redis的过期事件通知功能如下:
Redis的键过期通知是一种典型的发布-订阅模式。在Redis中,我们可以订阅到某些特定的事件。键过期事件就是其中之一。但需要注意,要使用这个功能,需要确保你的Redis服务器开启了相关配置。 下面是具体的步骤和示例:
1.首先需要确保Redis的配置文件(通常是redis.conf)中开启了键空间通知功能。你可以通过在配置文件中添加或修改如下配置实现:
notify-keyspace-events "Ex"
这里的"Ex"表示只监听键过期事件。如果需要监听其他类型的事件,可以参考Redis官方文档进行配置。
2.然后在Spring Boot应用中,可以使用RedisMessageListenerContainer来订阅Redis的键过期事件,并指定回调方法进行处理。示例如下:
@Configuration
public class RedisConfig {@Autowiredprivate RedisConnectionFactory redisConnectionFactory;@BeanRedisMessageListenerContainer container() {RedisMessageListenerContainer container = new RedisMessageListenerContainer();container.setConnectionFactory(redisConnectionFactory);// 订阅所有db的过期事件container.addMessageListener(new MessageListener() {@Overridepublic void onMessage(Message message, byte[] pattern) {String expiredKey = message.toString();if (expiredKey.startsWith("order:")) {// 处理订单超时逻辑String orderId = expiredKey.split(":")[1];// 这里调用你的服务类方法,处理订单超时逻辑// orderService.cancelOrder(orderId);}}}, new PatternTopic("__keyevent@*__:expired"));return container;}
}
在这个示例中,"__keyevent@*__:expired"是一个模式匹配的主题,它可以匹配所有数据库的键过期事件。当一个键过期时,onMessage方法会被调用,你可以在这里加入你的逻辑来处理订单的超时取消。
请注意,这里的代码只是一个基本示例。在实际使用中,你可能需要根据自己的需要对代码进行相应的调整和优化。
总结
以上三种方案都可以实现订单在30分钟内未支付则自动取消的需求。根据实际业务需求、系统负载和其他因素,可以选择最适合自己系统的实现方案。每种方案都有其优缺点,需要根据具体情况权衡。
相关文章:
SpringBoot 实现订单30分钟自动取消的策略
简介 在电商和其他涉及到在线支付的应用中,通常需要实现一个功能:如果用户在生成订单后的一定时间内未完成支付,系统将自动取消该订单。 本文将详细介绍基于Spring Boot框架实现订单30分钟内未支付自动取消的几种方案,并提供实例…...
Qt篇——QwtPainter::drawPie绘制扇形
QwtPainter::drawPie(QPainter *painter, const QRectF &rect, int startAngle, int angle); 一、参数含义: painter: 重绘函数中的painter对象 rect: 要绘制扇形的圆的外切矩形。 startAngle: 要绘制的扇形的起始角 …...
Mybatis Java API - SqlSession
正如前面提到的,SqlSession实例是MyBatis中最重要、最强大的类。它是您将找到执行语句、提交或回滚事务以及获取映射器实例的所有方法的地方。 SqlSession 类上有超过二十个方法,让我们将它们分成更易理解的组别。 Statement Execution Methods-语…...
java freemarker 动态生成excel文件
好久木有更新啦 抓住2023的小尾巴 浅浅更新一下吧~ 最近做了一个动态生成excel的功能,这里记录下部分功能,主要用到的是freemarker框架,spring就有带,我起的demo载入了一下freemarker的jar包 一、创建模板 首先可以创建一个e…...
第38节: Vue3 鼠标按钮修改器
在UniApp中使用Vue3框架时,你可以使用按键修饰符来更精确地处理键盘事件。以下是一个示例,演示了如何在UniApp中使用Vue3框架使用.left、.right和.middle按键修饰符: <template> <view> <input keydown"handleKeyDown&…...
redis cluster判断key属于那个分片。
一、判断阿里云 redis cluster,的key属于那个分片。 阿里云特有的命令info key 可以查看key属于那个slot,那个分片 命令行查看: xxxx:6379> info key xxxx_compressed_xxx slot:4941 node_index:9 xxxx:6379> cluster keyslot xxxx_…...
Centos7:Jenkins+gitlab+node项目启动(3)
Centos7:Jenkinsgitlabnode项目启动(1) Centos7:Jenkinsgitlabnode项目启动(1)-CSDN博客 Centos7:Jenkinsgitlabnode项目启动(2) Centos7:Jenkinsgitlabnode项目启动(2)-CSDN博客 Centos7:Jenkinsgitlabnode项目启…...
Linux安装GitLab教程
Linux安装GitLab教程 1、配置yum源 相当于新建一个文件,通过这个文件来安装gitlab vim /etc/yum.repos.d/gitlab-ce.repo 把这些配置粘进去 [gitlab-ce] nameGitlab CE Repository baseurlhttps://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el$releasever/ gp…...
react 之 美团案例
1.案例展示 2.环境搭建 克隆项目到本地(内置了基础静态组件和模版) git clone http://git.itcast.cn/heimaqianduan/redux-meituan.git 安装所有依赖 npm i 启动mock服务(内置了json-server) npm run serve 启动前端服务 npm…...
C基础使用
return 0; 语句用于表示退出程序。 一个程序有且只能有一个main函数的存在 安装编译环境: 安装vim: ubuntu里vim编辑器使用方法_ubuntu vim-CSDN博客 编译与运行: gcc hello.c //编译源文件 ./a.out //运行…...
Linux网络编程——Socket编程步骤及常用API
Sockt服务器和客户端的开发步骤 TCP connect()最好建立在listen()后,一旦监听到就建立连接。 UDP 常用API 包含头文件 #include<sys/types.h> #include<sys/socket.h>创建套接字(连接协议) 作用 用于根据指定的地址族、数据…...
数据挖掘 K-Means聚类
未格式化之前的代码: import pandas as pd#数据处理 from matplotlib import pyplot as plt#绘图 from sklearn.preprocessing import MinMaxScaler#归一化 from sklearn.cluster import KMeans#聚类 import os#处理文件os.environ["OMP_NUM_THREADS"] …...
医疗卫生行业网络安全需求发展
文章目录 一、行业安全建设需求分析1、等级保护2.0合规建设云计算技术大数据技术物联网技术移动互联网技术2、加强医疗数据安全保护加密存储与传输数据加强数据备份与恢复注重数据脱敏与分级保护3、强化网络安全制度管理完善应急预案与响应机制加强网络安全人员管理二、行业新技…...
【Unity热更新】学会AssetsBundle打包、加载、卸载
本教程详细讲解什么是AssetBundle压缩包机制!然后构建 AssetBundle、加载 AssetBundle 以及卸载 AssetBundle 的简要教程。这一个流程就是热更新! AssetBundles 简介 1.什么是AssetBundles? AssetBundles是Unity中一种用于打包和存储资源(如模型、纹理、声音等)的文件格…...
智能优化算法应用:基于指数分布算法3D无线传感器网络(WSN)覆盖优化 - 附代码
智能优化算法应用:基于指数分布算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于指数分布算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.指数分布算法4.实验参数设定5.算法结果6.…...
vue 监听浏览器关闭或刷新事件
vue 监听浏览器关闭或刷新事件 需求 web项目中使用socket时,涉及到关闭刷新浏览器多次连接问题,其中一个解决方法是在关闭或刷新浏览器时,将连接断开。 代码 <script> export default {// 可以在created、beforeMount或mounted生命…...
VuePress-theme-hope 搭建个人博客 2【快速上手】 —— 安装、部署 防止踩坑篇
续👆VuePress、VuePress-theme-hope 搭建个人博客 1【快速上手】 项目常用命令 vuepress dev [dir] 会启动一个开发服务器,以便让你在本地开发你的 VuePress 站点。vuepress build [dir] 会将你的 VuePress 站点构建成静态文件,以便你进行后…...
ClickHouse基础知识(四):ClickHouse 引擎详解
1. 表引擎的使用 表引擎是 ClickHouse 的一大特色。可以说, 表引擎决定了如何存储表的数据。包括: ➢ 数据的存储方式和位置,写到哪里以及从哪里读取数据。 默认存放在/var/lib/clickhouse/data ➢ 支持哪些查询以及如何支持。 ➢ 并发数…...
关于设计模式、Java基础面试题
前言 之前为了准备面试,收集整理了一些面试题。 本篇文章更新时间2023年12月27日。 最新的内容可以看我的原文:https://www.yuque.com/wfzx/ninzck/cbf0cxkrr6s1kniv 设计模式 单例共有几种写法? 细分起来就有9种:懒汉&#x…...
Python爱心光波完整代码
文章目录 环境需求完整代码详细分析环境需求 python3.11.4PyCharm Community Edition 2023.2.5pyinstaller6.2.0(可选,这个库用于打包,使程序没有python环境也可以运行,如果想发给好朋友的话需要这个库哦~)【注】 python环境搭建请见:https://want595.blog.csdn.net/arti…...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...
龙虎榜——20250610
上证指数放量收阴线,个股多数下跌,盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型,指数短线有调整的需求,大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的:御银股份、雄帝科技 驱动…...
简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...
【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...
高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
