/**
* 订单监控类
* 定时扫描所有待付款订单,超时自动取消
* Created by huangbaidong
* 2017/3/29.
*/
@Component
public class OrderMonitorJob { @Resource
private RedisUtil redisUtil; @Resource
private BsdOrderService bsdOrderService; @Resource
private BsdDFKOrderCacheManager bsdDFKOrderCacheManager; private boolean isLock = false; /**
* 待付款订单定时扫描类
* 定时扫描所有待付款订单,超时自动取消
*/
public void paymentTimeoutScan() {
if(!isLock) {
//加锁,防止定时器重复执行,
isLock = true;
try {
List<BsdDFKOrderCacheEntity> orders = bsdDFKOrderCacheManager.getAll();
if (BlankUtil.isNotEmpty(orders)) { List<String> removeIds = new ArrayList<>();//需要移除的订单 for (BsdDFKOrderCacheEntity order : orders) { if (Dictionary.ORDER_STATUS_DFK == order.getOrderStatus()) {
boolean isExpire = false;
if (order.isHasPromotion() == 1) {
//如果是有促销规则的订单,1小时未支付,自动取消订单
if (System.currentTimeMillis() - order.getOrderTime().getTime() > CommonConstants.hasRulePayTimeout) {
isExpire = true;
}
} else {
//如果是没有促销规则的订单,24小时未支付,自动取消订单
if (System.currentTimeMillis() - order.getOrderTime().getTime() > CommonConstants.hasNotRulePayTimeout) {
isExpire = true;
}
}
if (isExpire) { //1、自动取消订单(操作人ID传0)
bsdOrderService.cancel(order.getId(), 0l); //2、记录过期的订单,将订单从缓存中清除
removeIds.add(order.getId().toString()); System.out.println("------>订单[" + order.getCode() + "]超时未付款自动取消订单");
}
} else {
//不是待付款状态的订单,记录从缓存中清除
removeIds.add(order.getId().toString());
}
} //将不是待支付状态的订单,以及过期的未支付的订单从缓存中删除
if (BlankUtil.isNotEmpty(removeIds)) {
bsdDFKOrderCacheManager.removeFromCache(removeIds);
}
}
} finally {
//运行完后释放锁
isLock = false;
}
}
} }
/**
* 订单监控类
* 定时扫描所有待付款订单,超时自动取消
* Created by huangbaidong
* 2017/3/29.
*/
@Component
public class OrderMonitorJob { @Resource
private RedisUtil redisUtil; @Resource
private BsdOrderService bsdOrderService; @Resource
private BsdDFKOrderCacheManager bsdDFKOrderCacheManager; private boolean isLock = false; /**
* 待付款订单定时扫描类
* 定时扫描所有待付款订单,超时自动取消
*/
public void paymentTimeoutScan() {
if(!isLock) {
//加锁,防止定时器重复执行,
isLock = true;
try {
List<BsdDFKOrderCacheEntity> orders = bsdDFKOrderCacheManager.getAll();
if (BlankUtil.isNotEmpty(orders)) { List<String> removeIds = new ArrayList<>();//需要移除的订单 for (BsdDFKOrderCacheEntity order : orders) { if (Dictionary.ORDER_STATUS_DFK == order.getOrderStatus()) {
boolean isExpire = false;
if (order.isHasPromotion() == ) {
//如果是有促销规则的订单,1小时未支付,自动取消订单
if (System.currentTimeMillis() - order.getOrderTime().getTime() > CommonConstants.hasRulePayTimeout) {
isExpire = true;
}
} else {
//如果是没有促销规则的订单,24小时未支付,自动取消订单
if (System.currentTimeMillis() - order.getOrderTime().getTime() > CommonConstants.hasNotRulePayTimeout) {
isExpire = true;
}
}
if (isExpire) { //1、自动取消订单(操作人ID传0)
bsdOrderService.cancel(order.getId(), 0l); //2、记录过期的订单,将订单从缓存中清除
removeIds.add(order.getId().toString()); System.out.println("------>订单[" + order.getCode() + "]超时未付款自动取消订单");
}
} else {
//不是待付款状态的订单,记录从缓存中清除
removeIds.add(order.getId().toString());
}
} //将不是待支付状态的订单,以及过期的未支付的订单从缓存中删除
if (BlankUtil.isNotEmpty(removeIds)) {
bsdDFKOrderCacheManager.removeFromCache(removeIds);
}
}
} finally {
//运行完后释放锁
isLock = false;
}
}
} }

quartz 防止上一任务未执行完毕,下一时间点重复执行的更多相关文章

  1. java主线程等待所有子线程执行完毕在执行(常见面试题)

    java主线程等待所有子线程执行完毕在执行(常见面试题) java主线程等待所有子线程执行完毕在执行,这个需求其实我们在工作中经常会用到,比如用户下单一个产品,后台会做一系列的处理,为了提高效率,每个 ...

  2. ORACLE中查询语句的执行顺及where部分条件执行顺序测试

    Oracle中的一些查询语句及其执行顺序 原文地址:https://www.cnblogs.com/likeju/p/5039115.html 查询条件: 1)LIKE:模糊查询,需要借助两个通配符, ...

  3. C# Thread.Join的报错情形——论执行完的线程能够成功执行Join吗

    结论: 能, 执行完的线程调用Join不会抛出错误. Thread.Join()是什么? Join()函数用于阻塞地等待线程结束, 其行为是在线程A中调用了线程B的Join()后, 线程A将一直阻塞在 ...

  4. 重复执行用例(pytest-repeat)

    前言 平常在做功能测试的时候,经常会遇到某个模块不稳定,偶然会出现一些bug,对于这种问题我们会针对此用例反复执行多次,最终复现出问题来.自动化运行用例时候,也会出现偶然的bug,可以针对单个用例,或 ...

  5. Pytest系列(十三)- 重复执行之pytest-repeat的使用

    写在前面 这个插件,可以帮助我们很好的解决自动化测试过程中的一些偶线性bug难以复现的问题,但前提是,当前自动化脚本是独立的,不依赖任何其他脚本.个人觉得还是失败重运行的一种体现,就和TestNG是一 ...

  6. Java多线程--让主线程等待所有子线程执行完毕

    数据量很大百万条记录,因此考虑到要用多线程并发执行,在写的过程中又遇到问题,我想统计所有子进程执行完毕总共的耗时,在第一个子进程创建前记录当前时间用System.currentTimeMillis() ...

  7. Spring整合Quartz定时任务执行2次,Spring定时任务执行2次

    Spring整合Quartz定时任务执行2次,Spring定时任务执行2次 >>>>>>>>>>>>>>>&g ...

  8. 关于 使用python向qq好友发送消息(对爬虫的作用----当程序执行完毕或者报错无限给自己qq发送消息,直到关闭)

    以前看到网上一些小程序,在处理完事物后会自动发送qq消息,但是一直搞不懂是说明原理.也在网上找过一些python登陆qq发送消息的文字,但是都太复杂了.今天偶然看到一篇文章,是用python调用win ...

  9. C# 本进程执行完毕后再执行下一线程

    最近做了一套MES集成系统,由上料到成品使自动化运行,其中生产过程是逐步的,但是每一个动作都需要独立的线程进行数据监听,那么就需要实现线程等待. 代码: using System; using Sys ...

随机推荐

  1. C#多枚举值的写法与读法

    首先,定义枚举的时候必须是2,4,8,16这种2的次方的值. using System; using System.Collections.Generic; using System.Linq; us ...

  2. 关于release后retainCount还是1的问题

    转自:http://www.cocoachina.com/bbs/read.php?tid=175523 realse之后再调用还能调用的的问题,我做了这么多年也是经常遇到,也曾经试图寻找原因, 就像 ...

  3. js基本知识2

    一.提示框 1. 弹出警示框 alert(); window.alert(); window 窗口 2. 控制台输出 console.log() 3. 文档打印 document 文档 documen ...

  4. dubbo异步调用三种方式

    异步通讯对于服务端响应时间较长的方法是必须的,能够有效地利用客户端的资源,在dubbo中,消费端<dubbp:method>通过 async="true"标识. < ...

  5. jmap 查看内存使用直方图

    jps   -- 查看进程号 jmap -histo pid  查看堆内存中的对象数目.大小统计直方图, 如果带上live则表示先进行一次fullgc 再统计内存使用情况,如下: jmap -hist ...

  6. CSS学习笔记(6)--浮动,三列布局,高度宽度自适应

    百度ife任务三,要求中间宽度自适应,高度取三列最高者. 开始用position的relative和absolute,但是relative不能自适应宽,absolute不能加float浮动,撑不起来外 ...

  7. [每天一个Linux小技巧] 查看时钟源精度

    $ dmesg | grep clock [0.000000] OMAP clocksource: GPTIMER1 at 24000000 Hz  [0.000000] sched_clock: 3 ...

  8. Lucene 工作原理<转>

    Lucene是一个高性能的java全文检索工具包,它使用的是倒排文件索引结构.该结构及相应的生成算法如下: 0)设有两篇文章1和2 文章1的内容为:Tom lives in Guangzhou,I l ...

  9. Scala + Play + Sbt + Protractor = One Build

    欢迎关注我的新博客地址:http://cuipengfei.me/ 我所在的项目的技术栈选用的是Play framework做后端API,前端用Angular JS. 因为用了Scala和Play,构 ...

  10. python中的字典 和 集合

    python中字典是一种key-value的数据类型 字典的特性: 1.无序的 2.key必须的唯一的,so,字典天生去重 语法: 增加 修改 删除 查找 多级字典嵌套及操作 字典的其他用法 #set ...