自动取消失效订单(spring整合quartz)
来源:互联网 发布:印度it为何这么强 知乎 编辑:程序博客网 时间:2024/05/17 09:02
转载: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 这个注解标明上个任务没有执行完毕不会执行下个任务 */@DisallowConcurrentExecutionpublic 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; }}
阅读全文
1 0
- 自动取消失效订单(spring整合quartz)
- 自动取消失效订单(监听器 + quartz)
- JavaEE结合quartz实现订单自动失效功能
- Spring 整合 Quartz (一)
- Quartz(三)整合spring
- Spring-----Spring整合Quartz
- spring整合quartz,实现自助动态管理自动任务
- quartz 与Spring的整合-Quartz中的job如何自动注入spring容器托管的对象
- Quartz与Spring的整合-Quartz中的job如何自动注入spring容器托管的对象
- Quartz与Spring的整合-Quartz中的job如何自动注入spring容器托管的对象
- Quartz与Spring的整合-Quartz中的job如何自动注入spring容器托管的对象
- Quartz与Spring的整合-Quartz中的job如何自动注入spring容器托管的对象
- Quartz与Spring的整合-Quartz中的job如何自动注入spring容器托管的对象
- Spring+Quartz整合(2)之SimpleTrigger
- quartz(二)--与spring整合
- Spring整合Quartz(JobDetailBean方式)
- Spring整合Quartz(JobDetailBean方式)
- Spring整合Quartz(JobDetailBean方式)
- 再搞SQLServer添加Oracle链接服务器
- C#Winform调用libEasyPlayer总结
- Linux CentOS 6.6安装JDK1.7
- eclipse导入项目,项目名出现红叉的情况
- Windows版MYSQL5.7安装(压缩包版)
- 自动取消失效订单(spring整合quartz)
- mysql查询语句实例 复杂mysql查询
- Gartner存储魔力象限前四,阿里云如何成为“领头羊”?
- 可视化设计器的正确打开方式
- Attempt to invoke virtual method 'void android.support.v7.widget.ContentFrameLayout.setId(int)' on a
- 点击率预估算法:FM与FFM
- 如何编写更好的SQL查询
- Java实现AES加密,异常java.security.InvalidKeyException: Illegal key size 的解决
- 【JavaScript】将<input>的datetime-local的值转为Date型发送到服务器