自动取消失效订单(spring整合quartz)

转载

自动取消失效订单(spring整合quartz)

2017年09月01日 14:16:38 menghuanzhiming 阅读数:4157

转载:http://www.cnblogs.com/qingxinshujuan/p/5403878.html

CronTrigger最详细的Cron表达式范例参考:http://blog.csdn.net/zixiao217/article/details/53075009

任务需求:

  关闭超时未支付的订单,将订单信息置为失效状态

相关技术:

spring框架

  quartz框架定时调度

实现思路:

1.在服务启动时,查询数据库中的已下单未支付的订单数据,按下单时间先后存入队列中,先下单的存到头不,后下单存入队列尾部,取队列的头元素

2.检测与现在的时间,如果超过40分钟,则执行数据操作,即关闭订单,但是只关闭未支付的订单,之后在将头元素从队列移出,并取出下一个元素进行检测,以此类推

3.如果检测出时间未到40分钟,则线程等待相应的时间差,之后在执行订单操作

相关问题:

1.在执行时要防止轮询任务追尾,即在上一个job未执行完毕时就开始下一次轮询,解决方法是在job上加@DisallowConcurrentExecution注解,该注解的作用是让下一次job要等待当前job执行完毕

2.设置的轮询间隔是35分钟一次,订单超时是40分钟,中间有5分钟的时间差,为了防止订单被多次加入队列中,在加入订单队列时要注意去重

相关代码

quartz任务的job,用于检测数据库失效订单并将其关闭,代码如下:

package com.taotao.order.scheduler;

 

import java.text.ParseException;

import java.text.SimpleDateFormat;

import java.util.ArrayList;

import java.util.Date;

import java.util.LinkedList;

import java.util.List;

import java.util.Queue;

 

import org.apache.log4j.Logger;

import org.quartz.DisallowConcurrentExecution;

import org.quartz.JobExecutionException;

 

import com.taotao.order.pojo.Order;

 

/**

* quartz任务的job,用于检测数据库失效订单并将其关闭

* @DisallowConcurrentExecution 这个注解标明上个任务没有执行完毕不会执行下个任务

*/

@DisallowConcurrentExecution

public class CancelOrderJob1 {

//订单有效时间40分钟40 * 60 *

public static final long EFFTIVE_TIME = 1000;

private Logger logger = Logger.getLogger(CancelOrderJob1.class);

 

public void execute() throws JobExecutionException {

System.out.println("失效订单检测任务开始执行!");

Queue<Order> queue = new LinkedList<>();

 

// 在每次启动Job时去数据库查找失效订单,并加入到队列中(从数据库中查询,此处使用假数据)

List<Order> list = getInvalidOrder();

if (!list.isEmpty()) {

for (Order o : list) {

queue.offer(o);

}

}

// 获取队列的头元素,开始检测头订单是否失效

Order element = queue.peek();

while (element != null) {

//时间差值

Long diff = this.checkOrder(element);

if (diff != null && diff >= EFFTIVE_TIME) {

System.out.println("开始关闭订单" + element.getOrderId() + "下单时间" + element.getCreateTime());

// 弹出队列

queue.poll();

// 取下一个元素

element = queue.peek();

} else if (diff < EFFTIVE_TIME) {

try {

System.out.println("等待检测订单" + element.getOrderId() + "下单时间" + element.getCreateTime() + "已下单"

+ diff / 1000 + "秒");

//线程等待

Thread.sleep(EFFTIVE_TIME - diff);

} catch (InterruptedException e) {

e.printStackTrace();

logger.info("CancelOrderJob.checkOrder定时任务出现问题");

}

}

}

}

 

/**

* 获取订单的下单时间和现在的时间差

*

* @author wangpeiqing 2016年4月16日

* @param order

* @return

*

*/

public Long checkOrder(Order order) {

Date date = new Date();

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

Long diff = null;

if (order != null) {

Date createTime = order.getCreateTime();

try {

diff = sdf.parse(sdf.format(date)).getTime() - sdf.parse(sdf.format(createTime)).getTime();

} catch (ParseException e) {

e.printStackTrace();

}

}

// 返回值为毫秒

return diff;

}

 

/**

*

* @Title: getInvalidOrder

* @Description: TODO(生产订单假数据用于测试)

* @return List<Order> 返回类型

* @return

*/

private List<Order> getInvalidOrder() {

List<Order> invalidOrders = new ArrayList<>();

for (int i = 0; i < 50; i++) {

Order order = new Order();

order.setOrderId(String.valueOf(i));

order.setCreateTime(new Date());

invalidOrders.add(order);

}

return invalidOrders;

}

 

}

 

spring整合quartz配置方式

spring的配置文件如下:

<!-- 配置取消订单job类 -->

<bean id="cancelOrderJob1" class="com.taotao.order.scheduler.CancelOrderJob1"/>

<!-- 配置取消订单JobDetail 使用MethodInvokingJobDetailFactoryBean这种方式job类不需要实现Job接口-->

<bean id="cancelOrderJobDetail1"

class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">

<property name="targetObject">

<ref bean="cancelOrderJob1" />

</property>

<property name="targetMethod"> <!-- 要执行的方法名称 -->

<value>execute</value>

</property>

</bean>

<!-- 配置取消订单简单触发器trigger,启动项目立即执行 -->

<bean id="simpleTrigger1" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">

<property name="jobDetail" ref="cancelOrderJobDetail1"></property>

<property name="startDelay" value="500" />

<property name="repeatInterval" value="0" />

<property name="repeatCount" value="0" />

</bean>

<!-- 配置取消订单触发器trigger -->

<bean id="cancelOrderTrigger1" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean ">

<property name="jobDetail" ref="cancelOrderJobDetail1"></property>

<property name="cronExpression" value="0 0/2 * * * ?"></property>

</bean>

 

<!-- 配置调度工厂 -->

<bean id="SpringJobSchedulerFactoryBean"

class="org.springframework.scheduling.quartz.SchedulerFactoryBean">

<property name="triggers">

<list>

<!-- 取消订单的两个触发器 -->

<ref bean="simpleTrigger1" />

<ref bean="cancelOrderTrigger1" />

</list>

</property>

</bean>

 

订单实体类:

package com.taotao.pojo;

 

import java.util.Date;

 

public class TbOrder {

private String orderId;

 

private String payment;

 

private Integer paymentType;

 

private String postFee;

 

private Integer status;

 

private Date createTime;

 

private Date updateTime;

 

private Date paymentTime;

 

private Date consignTime;

 

private Date endTime;

 

private Date closeTime;

 

private String shippingName;

 

private String shippingCode;

 

private Long userId;

 

private String buyerMessage;

 

private String buyerNick;

 

private Integer buyerRate;

 

public String getOrderId() {

return orderId;

}

 

public void setOrderId(String orderId) {

this.orderId = orderId == null ? null : orderId.trim();

}

 

public String getPayment() {

return payment;

}

 

public void setPayment(String payment) {

this.payment = payment == null ? null : payment.trim();

}

 

public Integer getPaymentType() {

return paymentType;

}

 

public void setPaymentType(Integer paymentType) {

this.paymentType = paymentType;

}

 

public String getPostFee() {

return postFee;

}

 

public void setPostFee(String postFee) {

this.postFee = postFee == null ? null : postFee.trim();

}

 

public Integer getStatus() {

return status;

}

 

public void setStatus(Integer status) {

this.status = status;

}

 

public Date getCreateTime() {

return createTime;

}

 

public void setCreateTime(Date createTime) {

this.createTime = createTime;

}

 

public Date getUpdateTime() {

return updateTime;

}

 

public void setUpdateTime(Date updateTime) {

this.updateTime = updateTime;

}

 

public Date getPaymentTime() {

return paymentTime;

}

 

public void setPaymentTime(Date paymentTime) {

this.paymentTime = paymentTime;

}

 

public Date getConsignTime() {

return consignTime;

}

 

public void setConsignTime(Date consignTime) {

this.consignTime = consignTime;

}

 

public Date getEndTime() {

return endTime;

}

 

public void setEndTime(Date endTime) {

this.endTime = endTime;

}

 

public Date getCloseTime() {

return closeTime;

}

 

public void setCloseTime(Date closeTime) {

this.closeTime = closeTime;

}

 

public String getShippingName() {

return shippingName;

}

 

public void setShippingName(String shippingName) {

this.shippingName = shippingName == null ? null : shippingName.trim();

}

 

public String getShippingCode() {

return shippingCode;

}

 

public void setShippingCode(String shippingCode) {

this.shippingCode = shippingCode == null ? null : shippingCode.trim();

}

 

public Long getUserId() {

return userId;

}

 

public void setUserId(Long userId) {

this.userId = userId;

}

 

public String getBuyerMessage() {

return buyerMessage;

}

 

public void setBuyerMessage(String buyerMessage) {

this.buyerMessage = buyerMessage == null ? null : buyerMessage.trim();

}

 

public String getBuyerNick() {

return buyerNick;

}

 

public void setBuyerNick(String buyerNick) {

this.buyerNick = buyerNick == null ? null : buyerNick.trim();

}

 

public Integer getBuyerRate() {

return buyerRate;

}

 

public void setBuyerRate(Integer buyerRate) {

this.buyerRate = buyerRate;

}

}

 

 

package com.taotao.order.pojo;

 

import java.util.List;

 

import com.taotao.pojo.TbOrder;

import com.taotao.pojo.TbOrderItem;

import com.taotao.pojo.TbOrderShipping;

 

public class Order extends TbOrder{

 

private List<TbOrderItem> orderItems;

private TbOrderShipping orderShipping;

public List<TbOrderItem> getOrderItems() {

return orderItems;

}

public void setOrderItems(List<TbOrderItem> orderItems) {

this.orderItems = orderItems;

}

public TbOrderShipping getOrderShipping() {

return orderShipping;

}

public void setOrderShipping(TbOrderShipping orderShipping) {

this.orderShipping = orderShipping;

}

 

}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值