使用延遲隊列處理失效訂單問題

在處理訂單過程中,如果一個訂單生成之後,在特定時間內(比如15分鐘)沒有付款,那麼我們就要刪除這一筆訂單,釋放佔據的貨物資源。在這種場景下,最直觀的做法就是寫一個定時job, 每分鐘掃描一下數據庫的訂單表,如果訂單超過了15分鐘,那麼訂單狀態改爲刪除,並且商品表數量要加1,因爲剛剛刪除的訂單釋放了一個商品。這樣會給數據庫造成很大的壓力,而且如果長時間都沒有過期的訂單,而job依然會每分鐘跑一次,浪費資源。

 

JDK的延時隊列DelayQueue比較適應這種場景。延時隊列,最重要的特性就體現在它的延時屬性上,跟普通的隊列不一樣的是,普通隊列中的元素總是等着希望被早點取出處理,而延時隊列中的元素則是希望被在指定時間得到取出和處理,達到了規定的時間,則取出,沒有達到規定的時間,則不取出。具體的代碼邏輯如下。

 

1. 創建一個專門的DelayService, 它包含一個專門的延遲隊列容器delayQueue. 它實現了InitializingBean接口,所以在初始化的時候,會執行afterPropertiesSet方法,調用start方法,啓動一個線程, 這個線程會不斷的從延遲隊列中取出超時的消息,然後調用註冊的listener方法進行處理。take方法獲取並移除隊列首元素,如果隊列沒有過期元素則等待,爲阻塞式。

 

2. 可以在OrderService中註冊對於超時消息的處理邏輯,也可以在其他地方註冊,只要在容器初始化的時候,能把相應的listener注入到delayService的實例中。在訂單超時後,這裏會拿到超時訂單的訂單號,然後去數據庫裏做相應的操作,autoCancelOrder爲取消訂單,釋放相應的貨物。

3. 在用戶創建訂單的時候,會進行兩個操作,在數據庫中寫入訂單信息,然後就是在延遲隊列容器中加入一個消息,這個消息要包含有創建的這個訂單號碼。delayService.add方法會把延遲消息放入到容器中。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章