1

我一直在研究開發人員在領域驅動設計中設計/構建應用程序的許多常見方法(仍試圖理解作爲一個整體的概念)。我看到的一些例子包括通過事件聚合器使用事件。我喜歡這個概念,因爲它確實保持了應用程序的不同元素/域的解耦。回滾事件聚合器錯誤處理

我擔心的是:如何在錯誤情況下回滾操作?

例如:

說我有了一個爲了保存到數據庫,並命令的副本保存爲PDF到CMS命令的應用程序。應用程序觸發一個事件,即已創建新訂單並且訂閱此事件的PDF服務保存PDF。同時當提交訂單更改到數據庫時會引發異常。問題是pdf已被保存,但它們不是匹配的數據庫記錄。

我是否應該緩存先前處理的事件,並觸發一個新的錯誤事件,以查找緩存中的「撤消」操作?使用像這樣的命令模式?

或...事件聚合器不是一個好的模式。

編輯

我開始想,也許事件應該被用於不那麼「關鍵任務」的項目,如電子郵件和記錄。

我最初的想法是通過使用事件聚合器模式來限制依賴關係。

+0

請記住,您也可以使用內存中的事件;查看Udi Dahan域名事件救贖。 – JefClaes

回答

2

您希望在與數據庫操作相同的事務中提交事件。

在這種特定場景中,您可以將事件推送到隊列中,該隊列將註冊到您的事務中,以便事件永遠不會熄滅,除非聚合被持久化。這將使創建PDF最終一致;如果創建PDF失敗,則可以修復該問題,並自動重試。

也許你可以在eventual consistent domain events with RavenDB and IronMQ之前的帖子中獲得更多靈感。

2

在實際發生之前處理事件(提交)僅在事件處理程序參與事務時纔有效。使事件處理程序成爲事務性的(例如通過將PDF存儲在數據庫中),或在事務提交後發佈和處理事件。

+0

我看到關於將PDF存儲在數據庫中的觀點,但是如果PDF創建失敗,記錄創建後引發事件的第二點會導致相同的問題。 – Chris

+0

@Chris 2pc-commit如果你需要以原子方式存儲數據庫和cms,但是我非常懷疑這種必要性。 – Hippoom

+0

@Chris這不是同一個問題。創建PDF時失敗是一個錯誤,但爲不存在的訂單創建PDF會產生不一致。事件處理程序可能會失敗 - 修復問題並再次處理事件。 –