素材牛VIP会员
用户提交订单,30分钟后没付款取消订单功能分析
 lo***ng  分类:PHP代码  人气:2917  回帖:18  发布于6年前 收藏

我先在要做这样的功能:

用户在创建订单后,订单表中记入的是未付款状态,如果用户在30分钟后,还未付款,然后就把该订单给取消。
关于用户创建订单,30分钟后还没付款,取消该订单的逻辑是怎么实现的。
我自己的想了两个方案:
(1):客户端记入这个订单,如果在30分钟后还没有付款,就发送一个请求,调用后台的接口,来取消这个订单。
(2):服务端写个脚本,然后crontab来执行,来监控在30分钟还没有付款的订单,如果有就取消订单。

各位大神,这是我想到的两个方案,不知道合不合适,求大神们指点指点,感激不尽。

 标签:php

讨论这个帖子(18)垃圾回帖将一律封号处理……

Lv2 入门
熊***子 学生 6年前#1

我觉得性能最好的就是高票回答,也就是和php的session过期gc回收机制一样的原理。

如果理解不了那个方法,也可以试试看redis里面加过期时间的办法,这种方法有个缺陷就是如果某个redis节点当机,可能会导致那个节点下的用户订单丢失,这个时候就需要多机同步备份了。

Lv1 新人
10***85 产品经理 6年前#2

不知道你的客户端是什么,但是方案1很依赖客户端,订单决策不应该由客户端发起

方案2的话就要考虑你的执行密度,要知道每时每刻都会有新订单发起的,每时每刻也会有订单过期。

用一些成熟的带TTL控制的方案吧,比如redis。


我之前的做法是在每次查询这个订单时候检查过期,被动过期。

比如,查询订单细节时,再去检查是否过期然后再处理。
当然,如果这条数据不被访问可能永远不会过期,直到有人访问它。

有点像薛定谔的猫,在你打开盒子(检查订单)之后,才知道它是否过期。所以叫被动过期

Lv4 码徒
进***新 学生 6年前#3

最近的项目也有类似的需求。我这边是被动更新 + crond 主动更新两种方式,因为是抢购,下单扣库存,5分钟不支付马上过期恢复库存。

当碰到支付完成到回跳时,订单刚好过期的时候,直接将订单设置为待退款状态,然后走另一个定时任务完成退款。

Lv5 码农
橙***哒 JAVA开发工程师 6年前#4

客户端数据被篡改就能无限修改这个时间阈值了

Lv7 码师
un***oo 职业无 6年前#5

我的思路有点不同,有类似Redis, 或者打个比方说Cookie吧(当然不能直接就用cookie)

//新创建订单后
$order_sn = '123456'; //订单号

//这个方法自己看着建立,实际项目中没有这个函数方法,这只是思路!
cookie()->push($order_sn, 1800);

//支付订单等操作时
//先检测cookie中是否还有这个订单号
if(!cookie()->has($order_sn)){
    die('该订单已过期!');
}
Lv5 码农
迷***文 JS工程师 6年前#6

想到了一个 为每个订单创建一次性定时任务 以创建时间为起点三十分钟后 检查一次 处理逻辑

Lv6 码匠
yy***15 页面重构设计 6年前#7
  1. 订单创建成功后放进redis 超时时间设置为30分钟

  2. 做个crontab定时任务 检查订单是否超过30分钟

推荐第一种方法

Lv4 码徒
sh***ng 学生 6年前#8

创建订单后,放个30分钟执行的任务到工作队列。

补充一:

工作队列具体流程:

  1. 用户创建订单A

  2. 生成30分钟后执行的任务,任务内容是:检查订单A是支付成功,如果没支付则标记为失效订单

  3. 用户支付,如果订单已失效,说明已经过了30分钟,否则标记订单支付成功

Laravel自带的队列很方便:Queues

胡思乱想:

直接用Redis的过期功能把订单删了并不好,或者要预留多一点时间,不要准确30分钟过期。

考虑这种情况:

对接微信支付,用户在29分59秒支付成功,微信在支付成功时发送异步给服务器,1.1秒后到达服务器,而这个时候订单已经被删了。

在生成微信的订单时判定一次即可。

Lv3 码奴
ch***az 职业无 6年前#9

写个定时任务脚步,一分钟执行一次,查库操作。
查询 未支付 并且 订单生产时间大于当前时间30分钟的
每次查询10条,去执行取消订单逻辑

Lv3 码奴
默***H 学生 6年前#10

守护进程处理

上一页12下一页
 文明上网,理性发言!   😉 阿里云幸运券,戳我领取