一般情况,我们的想到跑定时脚本去做相关的处理。这个想法是没错的。肯定使用到定时脚本。
方法一:没有借用别的技术,就是查询出来未付款的订单,遍历方式是还原库存、优惠券等的问题
$order = Order::where(['is_pay'=>0])->where('addtime','<=',time()-86400)->selete();
foreach($order as $val){
//处理相关的代码
}
方法二:借助redis优势,开始的找到对应的订单,对其操作
思路:一般是下单的时候,已经减去库存等信息,就在下单的地方,我们把订单id 和 addtime 组合放在redis队列里面,我们读取队列的时候,list 分割下单时间与当前的时间对比,若是超了24小时就操作对应的订单的操作。
下单写入队列代码
//假设订单id = 29 addtime = 1298482849
$order_id = 29;
$addtime = 129848284;
$redis = new Redis();
$redis->lpush('order_list',$addtime.'-'.$order_id);
定时脚本部分代码
$redis = new Redis();
$key = 'order_list';
$len = $rediss->llen($key);
for ($i = 1; $i<=$len;$i++){
$vaule = $rediss->Rpop($key);
list($addtime,$order_id) = explode('-',$vaule);
if($addtime <= time() - 86400){
//处理相关代码
$order = Order::where(['id'=>$order_id,'is_pay'=>0,'is_send' => 0])->find();
}else{
//把值存放回去
$rediss->rpush($key,$vaule);
break;//按照时间放进去,碰到一个不符合的,证明后面进来的订单就是没超过24小时的。就没必要再循环下去了
}
}
注意:若是过几分,用户支付了,这时我们应该把对应队列的数据删除
这是用到redis的lren 命令,一般是在支付成功回调里面执行
部分代码
$order = Order::where(['order_no'=> $order_no])->find();//
$redis = new Redis();
$key = 'order_list';
$redis->lrem($key,$order->addtime.'-'.$order->id);//这样就能删除队列对应的值
区别:下单数多的时候,第一种消耗的资源大些,查询速度就慢。第二种,借用Reids优势,执行的速度快,节省了mysql的开销。不过也有缺点就是需要的redis的空间大小。
以上的方案,可以各自考量,根据的业务来做。