最近项目中遇到一个问题:订单创建后,5分钟没有支付的话,则取消订单。
针对这个问题,我和同事商讨出三个解决方案:
1、订单创建的时候,插入一条订单截止时间记录,包含订单id,截止订单支付截止时间等信息。spring定时器每秒查询记录,循环遍历所有记录,如果截止时间小于当前时间,则取消订单.
2、创建工具bean,服务启动时查询数据库订单截止时间记录,保存在list中(也可以放在cache里)。新启线程,每秒跑一次,遍历list,如果截止时间小于当前时间,则取消订单。同时,新建订单时,往list和数据库中添加数据,完成支付或者用户主动取消订单时,往list和数据库中删除数据,保持list和数据库的一致性。
3、利用信息队列,设置延时参数(可以参考笔者另一篇rabbitmq的文章)
第一个方案由于每秒查询数据库,耗时耗资源,故不推荐,这里主要谈一下第二个方案。
步骤:
1、spring配置自动扫描
<context:component-scan base-package="com.hz.sunday.xlcl.TjscOrderEndPayTimeAutoBean"/>
2、新建OrderEndPayTimeAutoBean.java
package com.hz.sunday.xlcl.service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.hz.sunday.xlcl.entity.mysql.order.TjscOrderEndPayTime;
import com.hz.sunday.xlcl.service.mysql.order.TjscOrderEndPayTimeService;
//自动装载
@Component
//继承Thread方便新启线程
public class TjscOrderEndPayTimeAutoBean extends Thread{
@Autowired
private TjscOrderEndPayTimeService tjscOrderEndPayTimeService;
//新建全局变量,订单截止时间记录将存放在这里
List<TjscOrderEndPayTime> tjscOrderEndPayTimeList = new ArrayList<TjscOrderEndPayTime>();
//服务启动自动加载
@PostConstruct
public void init() {
Map<String, Object> param = new HashMap<String, Object>();
//获取数据库存在的订单截止时间记录
tjscOrderEndPayTimeList=tjscOrderEndPayTimeService.select(param);
//开始线程
this.start();
}
//重写run方法,this.start后将运行此方法
@Override
public void run(){
for (int i = 0; i < 1; i--) {
try {
//每秒运行
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//遍历订单截止时间记录,取消对应订单(返还库存),删除数据库数据,删除list中对应的信息(你们自己写啊)
for (TjscOrderEndPayTime tjscOrderEndPayTime : tjscOrderEndPayTimeList) {
System.out.print(tjscOrderEndPayTime);
}
}
}
//list中添加数据,创建订单是调用
public void addOrderEndPayTimeList (TjscOrderEndPayTime tjscOrderEndPayTime){
tjscOrderEndPayTimeList.add(tjscOrderEndPayTime);
}
//list中删除数据,完成支付或者取消订单时调用
public void removeOrderEndPayTimeList (TjscOrderEndPayTime tjscOrderEndPayTime){
if (tjscOrderEndPayTimeList.contains(tjscOrderEndPayTime)) {
List<TjscOrderEndPayTime> removeList = new ArrayList<TjscOrderEndPayTime>();
removeList.add(tjscOrderEndPayTime);
tjscOrderEndPayTimeList.removeAll(removeList);
}
}
}
这样就完成了,是不是很简单。还有一点需要注意全局变量list中的bean,在新增、查询、删除这个bean的时候,一定要保持bean中的元素一致。假如你在list中新增bean的时候,bean的id是空的,然后删除的时候bean的其他元素都一致,但是id有数据,这样是你删除不成功的。