延遲執(zhí)行業(yè)務(wù)

在業(yè)務(wù)處理中,我們有時(shí)候會碰到一些場景,他們需要執(zhí)行多個(gè)步驟才能算完成,然而這幾個(gè)步驟并非是連續(xù)立即執(zhí)行的。

舉一個(gè)例子,在處理訂單業(yè)務(wù)的時(shí)候,我們接收到訂單,需要將訂單保存到數(shù)據(jù)庫中,然后,要將其存入Redis緩存,完了還要將其轉(zhuǎn)發(fā)給其他相關(guān)系統(tǒng)。轉(zhuǎn)發(fā)其他系統(tǒng)的過程也是成對的操作,需要將轉(zhuǎn)發(fā)的數(shù)據(jù)存入一份處理表同時(shí)向消息隊(duì)列中也傳一份,根據(jù)發(fā)送到對方系統(tǒng)中的反饋消息進(jìn)行相應(yīng)處理(處理成功則將處理表中對應(yīng)數(shù)據(jù)刪除,處理失敗則對該數(shù)據(jù)進(jìn)行重新發(fā)送,或者根據(jù)業(yè)務(wù)需求重新操作)。

這樣的業(yè)務(wù),會有幾個(gè)顯而易見的問題。

問題一、保存數(shù)據(jù)庫的操作需要事務(wù),但事務(wù)中很難包括對Redis和隊(duì)列的操作。

問題二、向外系統(tǒng)發(fā)送數(shù)據(jù)的過程,可快可慢,在最快的場景中,消息發(fā)送出去,對方立即有相應(yīng)的反饋回來,但本地?cái)?shù)據(jù),可能還沒有保存到數(shù)據(jù)庫中,此時(shí),無法將該數(shù)據(jù)跟數(shù)據(jù)庫中聯(lián)系起來,結(jié)果將會出現(xiàn)數(shù)據(jù)錯(cuò)誤。

一個(gè)解決方案就是,將數(shù)據(jù)庫操作集中到一起放在事務(wù)中處理,將其對應(yīng)的額外操作,放到事務(wù)外面,統(tǒng)一執(zhí)行。

這樣的解決方案,可以保證事務(wù)的完整性,當(dāng)數(shù)據(jù)庫操作失敗的時(shí)候,數(shù)據(jù)庫事務(wù)回滾,其余操作也可以終止。另外也不會發(fā)生消息接收系統(tǒng)反饋結(jié)果太快而導(dǎo)致的數(shù)據(jù)錯(cuò)誤的情況。

但這不是完美的方案。

我們在執(zhí)行業(yè)務(wù)的時(shí)候,“保存并緩存訂單”和“保存并發(fā)送消息”,都是成對的操作,如果將他們割裂,業(yè)務(wù)和代碼將會變得不直觀。

是否可以有個(gè)更好的解決方案呢?

這個(gè)解決方案,我們稱之為延遲執(zhí)行模式。


我們在處理業(yè)務(wù)邏輯的時(shí)候,在事務(wù)中我們正常處理數(shù)據(jù)庫操作,與此同時(shí),在相應(yīng)操作同時(shí)將對應(yīng)的需要延遲執(zhí)行的邏輯定義到一個(gè)延遲執(zhí)行的類中。這個(gè)類我們稱之為DelayedExecutor。并將這個(gè)延遲執(zhí)行對象放到一個(gè)鏈表中,鏈表將在整個(gè)業(yè)務(wù)邏輯的上下游傳遞,在事務(wù)操作結(jié)束后,通過遍歷鏈表來執(zhí)行那些需要延遲執(zhí)行的方法。

該模式的核心在于以下幾個(gè)類和接口

DelayablelService??帶有延遲任務(wù)的業(yè)務(wù)邏輯

public interface DelayablelService <T>?這是一個(gè)接口?

其核心方法是?void doBusiness(T param);??

處理業(yè)務(wù)邏輯,并在處理業(yè)務(wù)邏輯時(shí),將需要延遲執(zhí)行的邏輯定義好

我們所有要執(zhí)行的代碼就是從這里開始

param?是業(yè)務(wù)數(shù)據(jù)參數(shù)? ?


DelayedExecutor?需要被延遲執(zhí)行的邏輯接口

public interface DelayedExecutor

這是一個(gè)接口?其中定義了void execute();方法

該類在業(yè)務(wù)邏輯中,通過匿名內(nèi)部類的方式實(shí)現(xiàn)。將業(yè)務(wù)方法中的數(shù)據(jù)傳入該方法中。


DelayedExecutorHandler?延遲執(zhí)行內(nèi)容管理

public class DelayedExecutorHandler?

一個(gè)管理類,管理DelayedExecutor?

類中有一個(gè)內(nèi)部list?private List<DelayedExecutor> executors;

通過 public void add(DelayedExecutor executor)方法?

在DelayablelService的doBusiness?執(zhí)行以后,

調(diào)用public void handle()方法執(zhí)行延遲執(zhí)行的邏輯。


DelayedCallHandler?執(zhí)行業(yè)務(wù)并調(diào)用被延遲的方法

public class DelayedCallHandler<T>?這是一個(gè)類

public void handle(DelayablelService?businessService, T param)?

通過這個(gè)方法調(diào)用?DelayablelService中的?doBusiness方法,

在?doBusiness執(zhí)行完以后,通過DelayedExecutorHandler?獲取到?延遲執(zhí)行的對象列表遍歷并執(zhí)行其邏輯

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 概念:微服務(wù)就是一些可獨(dú)立運(yùn)行、可協(xié)同工作的小的服務(wù)。微服務(wù)是現(xiàn)在特別流行的服務(wù),微服務(wù)的字面意思是大家都很好理解...
    程序員技術(shù)圈閱讀 3,456評論 2 47
  • ORA-00001: 違反唯一約束條件 (.) 錯(cuò)誤說明:當(dāng)在唯一索引所對應(yīng)的列上鍵入重復(fù)值時(shí),會觸發(fā)此異常。 O...
    我想起個(gè)好名字閱讀 5,980評論 0 9
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對...
    cosWriter閱讀 11,667評論 1 32
  • 轉(zhuǎn) # https://www.cnblogs.com/easypass/archive/2010/12/ 08/...
    呂品?閱讀 10,135評論 0 44
  • 乖乖,今天已經(jīng)5號了,不知道你在火車上怎么樣啊! 今天,遇到很多不開心的事情.好想給你說說阿!雖然你已經(jīng)不在我身邊...
    xiao錢錢閱讀 133評論 0 0

友情鏈接更多精彩內(nèi)容