2014-03-04 52 views
0

考慮一個函數:IsWalletValid(walletID)。如果walletID存在於數據庫中,它將返回true,並更新'last_accessed_time'字段。分離命令和查詢時更新上次訪問時間

定期運行一項任務,以移除任何在設定的時間段內未被訪問的錢包。

似乎是一個簡單的解決方案,但我們想要做什麼,但IsWalletValid()有副作用,因爲它寫入數據庫。

我們是否應該添加額外的'UpdateLastAccessedTime(walletID)'功能?每次我們調用IsWalletValid()時,我們還需要記住調用UpdateLastAccessedTime(walletID)。

+0

爲什麼你需要更新'last_accessed_time'字段? –

+0

如果沒有人訪問一個錢包幾天,它不再需要,可以刪除。 – GarethOwen

+2

CQRS最適合於事件採購,因爲否則重建輔助(持久性)商店變得非常困難。隨着事件採購,你永遠不會刪除任何東西,所以如果你想刪除錢包,我想知道如果CQRS是正確的架構..? –

回答

0

確認錢包有效並更新它的last_accessed_time字段需要事務一致(ACID)嗎?您可以在這裏使用最終的一致性:

方法IsWalletValid發佈WalletAccessed事件,則事件處理程序異步更新last_accessed_time

+0

我不同意這個答案(我相信大多數CQRS的擁護者會同意我的觀點):查詢應該永遠不會發佈一個事件。只有命令發佈事件。 –

+0

是的,我同意在這種情況下,查詢方不應該改變系統,即引發事件。 – boz

+0

@JoshKodroff爲什麼不呢?一個事件表明_interesting_在您的系統中發生了,無論它是狀態更改(域事件),發送的電子郵件(集成事件)還是執行的查詢(基礎架構,或者在此特定情況下的域事件)。你錯了命令:命令不發佈事件,命令**改變**聚合狀態。聚合負責發佈事件。如果'IsWalletValid'有副作用,我更願意將它明確地建模爲一個事件,而不是在讀取側更新域。 –

0

如果last_accessed_time未被域邏輯訪問來決定任何寫入處理,這可能只是只讀投影的一個方面。似乎與其他更詳細的閱讀審計問題一樣,這是同樣的擔憂。僅僅因爲數據的編寫和維護並不意味着它必然是系統寫模型的一部分。如果您確實希望將其作爲域的一部分實施並可能存儲在同一個事件存儲中,則可以將其視爲在被審計的原始聚合的邊界之外的單獨的審計上下文。