我們已經構建了一個基於CQRS的系統,使用關係數據庫在域側和NoSQL DB在讀取側。領域方面遵循經典的關係方法,而讀方是非規範化的。 使用命令處理程序發出的事件完成數據複製和轉換。CQRS:更新不帶事件源的讀取模型
我有一個關於讀取端同步的兩個問題:
什麼是使用的域端的關係數據完全重建閱讀模式的最佳方式?
我們假設讀取模型不同步。 但即使它始終處於同步狀態,也可能需要導入測試數據庫 或執行一些批量操作。所以人們可能希望 從現有的寫入模型運行系統,而沒有相應的同步讀取模型。由於我們不使用事件採購,因此不存在重播所有事件的方式。
我目前考慮一個
ReadModelBuilder
,它基本上做一個 SELECT * FROM在每個表上,並將每個實體轉換爲讀取端 表示。但是這會引入冗餘。 ReadModelBuilder需要知道轉換是如何完成的。 因此,在Command Handler執行一些寫入操作後,通常會執行讀取端同步 的事件處理程序。我想過放棄事件處理程序,並在每個類級別上用 取代同步機制。 例如而不是
FooRenamedEventHandler
重命名foo.name
,它會調用FooReadModelBuilder
,它將重寫完整的Foo
實例的 。 但我認爲這有弊端。在閱讀模型中,FooRenamedEventHandler可以更好地處理 以及foo.name
的冗餘用法。UPDATE: 另一種方法可以讓
ReadModelBuilder
創建讀取模型實體將通過分割域實例爲事件,當順序執行,這將構建完整的讀端實體。 例如:Article
域實體有一個Name
和一個Price
。 要構建讀取模型,ReadModelBuilder
可以檢查域實體併發出ArticleCreatedEvent
,ArticleRenamedEvent
和ArticlePriceChangedEvent
。這樣,轉換邏輯將保留在事件處理程序中,但仍可從某種大容量複製機制調用。例如,ReadModelBuilders看起來是這樣的:
_
interface IReadModelBuilder<TEntity>
{
//// Returns a sequence of events which replicate the read-model
//// when executed by the event handlers.
Event[] GetReplicationSequence(TEntity instance);
}
UPDATE年底
_
- 您通常如何檢測不同步的讀取模型?是否有一般的最佳做法?
在此先感謝您。
這是一個有趣的問題。您有什麼情況可以避免同步? –
我想任何嚴重軟件系統的高效使用都會遇到數據庫必須交換或批量轉換的情況。這可能是由軟件錯誤引起的。由於巴士系統中的錯誤。由於操作失敗。這可能是因爲有人可能想要部署測試數據庫。或者因爲必須部署較舊的備份。當然可以保留兩個數據庫作爲備份,但想象一下讀取端備份丟失或損壞。 – mbnx
我明白了。如果你不堅持事件(即不使用事件源),那麼你不能輕易重建一個讀取模型。你的'重建者'必須以某種方式嘗試對寫模型進行逆向工程,並製造一些奇怪的事件,因爲寫模型甚至不能包含所有的信息,因爲它不需要它來完成他的工作 –