Java實(shí)現(xiàn)商城訂單超時(shí)取消功能
大多數(shù)的B2C商城項(xiàng)目都會(huì)有限時(shí)活動(dòng),當(dāng)用戶下單后都會(huì)有支付超時(shí)時(shí)間,當(dāng)訂單超時(shí)后訂單的狀態(tài)就會(huì)自動(dòng)變成已取消 ,這個(gè)功能的實(shí)現(xiàn)有很多種方法,本文的實(shí)現(xiàn)方法適合大多數(shù)比較小的商城使用。
實(shí)現(xiàn)原理:
利用 jdk 的 DelayQueue的阻塞隊(duì)列的特性實(shí)現(xiàn)。在項(xiàng)目啟動(dòng)時(shí)開啟一個(gè)線程處理 DelayQueue 隊(duì)列里彈出的超時(shí)訂單對(duì)象,訂單未超時(shí)該線程處于等待中。
DelayQueue的簡(jiǎn)單介紹:
DelayQueue類的主要作用:是一個(gè)無界的BlockingQueue,用于放置實(shí)現(xiàn)了Delayed接口的對(duì)象,其中的對(duì)象只能在其到期時(shí)才能從隊(duì)列中取走。這種隊(duì)列是有序的,即隊(duì)頭對(duì)象的延遲到期時(shí)間最長(zhǎng)。注意:不能將null元素放置到這種隊(duì)列中。
實(shí)現(xiàn)方式 :
1.創(chuàng)建一個(gè)實(shí)現(xiàn)Delayed接口的 order 類并重寫compareTo和 getDelay方法
2.創(chuàng)建一個(gè)幫助類OrderCollection(訂單的增刪查)
3. 創(chuàng)建CancellOrder類
在生成訂單時(shí)將訂單號(hào)創(chuàng)建時(shí)間和過期時(shí)間封裝成一個(gè)實(shí)現(xiàn)Delayed接口的對(duì)象存入DelayQueue隊(duì)列中,當(dāng)該訂單支付完成后將該對(duì)象從隊(duì)列中移除,(為了保證不丟失訂單建議在項(xiàng)目啟動(dòng)時(shí)將數(shù)據(jù)庫(kù)中的符合條件的訂單初始化到DelayQueue隊(duì)列中 )
實(shí)現(xiàn)代碼如下:
/** * 類說明 * * @author grl * @date 2019年12月16日 新建 */ public class Order implements Delayed { private String orderShopNum; /** * 1-普通活動(dòng) 2-限時(shí)活動(dòng) 3-拼購(gòu)活動(dòng) */ private int orderType; private long orderCreateTime; private long expTime; public Order(String orderShopNum, int orderType, Date createTime) { if (StringUtils.isNotBlank(orderShopNum)) { this.orderShopNum = orderShopNum.trim(); } if (createTime == null) { this.orderCreateTime = System.currentTimeMillis(); } else { this.orderCreateTime = createTime.getTime(); } this.orderType = orderType; if (orderType == 2) { this.expTime = TimeUnit.MILLISECONDS.convert(Const.LIMIT_ACTIVITY_EXPIRATION_TIME, TimeUnit.MINUTES) + createTime.getTime(); }if(orderType == 3){ this.expTime = TimeUnit.MILLISECONDS.convert(Const.LIMIT_GROUP_BUY_EXPIRATION_TIME, TimeUnit.MINUTES) + createTime.getTime(); } else { this.expTime = TimeUnit.MILLISECONDS.convert(Const.ORDER_PAYMENT_DEADLINE, TimeUnit.DAYS) + createTime.getTime(); } } public String getOrderShopNum() { return orderShopNum; } public long getOrderCreateTime() { return orderCreateTime; } public long getExpTime() { return expTime; } public int getOrderType() { return orderType; } @Override public int compareTo(Delayed o) { return Long.valueOf(this.expTime).compareTo(Long.valueOf(((Order) o).expTime)); } @Override public long getDelay(TimeUnit unit) { return unit.convert(this.expTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS); } } /** * 類說明 * * @author grl * @date 2019年12月16日 新建 */ public class OrderCollection { /** * 訂單管理集合 */ private static DelayQueue<Order> orderList = new DelayQueue<Order>(); private OrderCollection() { } /** * 獲取訂單集合 * @author grl * @return */ protected static DelayQueue getOrderCollection() { return orderList; } /** * 向集合中添加訂單 * * @author grl * @param order * @return */ public static boolean add(Order order) { boolean flag = false; if (order != null && StringUtils.isNotBlank(order.getOrderShopNum())) { flag = orderList.offer(order); } return flag; } /** * 從集合中刪除訂單 * * @author grl * @param orderShopNum * @return */ public static boolean remove(String orderShopNum) { boolean flag = false; Order thisOrder = null; if (StringUtils.isNotBlank(orderShopNum)) { orderShopNum = orderShopNum.trim(); for (Order order : orderList) { String orderNum = order.getOrderShopNum(); if (orderNum.equals(orderShopNum)) { thisOrder = order; } } if (thisOrder != null) { flag = orderList.remove(thisOrder); } } return flag; } /** * 獲取訂單的過期剩余時(shí)間 * * @author grl * @param orderShopNum * @param unit * @return -1 已經(jīng)過期 */ public static long getDelay(String orderShopNum) { long time = -1; if (StringUtils.isNotBlank(orderShopNum)) { orderShopNum = orderShopNum.trim(); for (Order order : orderList) { String orderNum = order.getOrderShopNum(); if (orderNum.equals(orderShopNum)) { time = order.getDelay(TimeUnit.MILLISECONDS); if(time<5000) { time = -1; } } } } return time; } } /** * 類說明 * * @author grl * @date 2019年12月16日 新建 */ @Component public class CancellOrder implements Runnable { private static final Logger log = LoggerFactory.getLogger(CancellOrder.class); @Override public void run() { while (true) { try { Order take = OrderCollection.getOrderCollection().take(); String orderShopNum = take.getOrderShopNum(); int orderType = take.getOrderType(); // 業(yè)務(wù)邏輯操作 } catch (InterruptedException e) { e.printStackTrace(); log.error("CancellOrder DelayQueue 錯(cuò)誤 {}", e.getMessage()); } } } }
總結(jié)
以上所述是小編給大家介紹的Java實(shí)現(xiàn)商城訂單超時(shí)取消功能,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
如果你覺得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!
- Java實(shí)現(xiàn)訂單超時(shí)未支付自動(dòng)取消的8種方法總結(jié)
- Java使用延時(shí)隊(duì)列搞定超時(shí)訂單處理的場(chǎng)景
- Java?實(shí)現(xiàn)訂單未支付超時(shí)自動(dòng)取消功能(京東商城為例)
- 基于Java創(chuàng)建一個(gè)訂單類代碼實(shí)例
- java后臺(tái)實(shí)現(xiàn)支付寶支付接口和支付寶訂單查詢接口(前端為APP)
- Java微信支付之關(guān)閉訂單
- java web在高并發(fā)和分布式下實(shí)現(xiàn)訂單號(hào)生成唯一的解決方案
- Java開發(fā)如何把數(shù)據(jù)庫(kù)里的未付款訂單改成已付款
相關(guān)文章
基于springMvc+hibernate的web application的構(gòu)建
下面小編就為大家?guī)硪黄趕pringMvc+hibernate的web application的構(gòu)建。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-10-10Java的Hibernate框架結(jié)合MySQL的入門學(xué)習(xí)教程
Java世界中的SSH三大框架是Web開發(fā)方面的人氣組合,Hibernate便是其中之一,這里我們來整理一下Java的Hibernate框架結(jié)合MySQL的入門學(xué)習(xí)教程,需要的朋友可以參考下2016-07-07教你如何測(cè)試Spring Data JPA的Repository
Spring Data JPA 提供了一些便捷的方式來測(cè)試這種持久層的代碼,常見的兩種測(cè)試類型是集成測(cè)試和單元測(cè)試,本文通過示例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-08-08SpringBoot詳解自定義Stater的應(yīng)用
Springboot的出現(xiàn)極大的簡(jiǎn)化了開發(fā)人員的配置,而這之中的一大利器便是springboot的starter,starter是springboot的核心組成部分,springboot官方同時(shí)也為開發(fā)人員封裝了各種各樣方便好用的starter模塊2022-07-07springboot整合spring-data-redis遇到的坑
使用springboot整合redis,使用默認(rèn)的序列化配置,然后使用redis-client去查詢時(shí)查詢不到相應(yīng)的key.問題出在哪,怎么解決呢?下面小編給大家?guī)砹藄pringboot整合spring-data-redis遇到的坑,需要的的朋友參考下吧2017-04-04Spring Date jpa 獲取最新一條數(shù)據(jù)的實(shí)例代碼
這篇文章主要介紹了Spring Date jpa 獲取最新一條數(shù)據(jù)的實(shí)例代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-10-10java關(guān)于并發(fā)模型中的兩種鎖知識(shí)點(diǎn)詳解
在本篇文章了小編給大家整理的是一篇關(guān)于java關(guān)于并發(fā)模型中的兩種鎖知識(shí)點(diǎn)詳解內(nèi)容,有興趣的朋友們可以學(xué)習(xí)下。2021-04-04