3

聚合根源在那裏可以控制狀態變化 - 當前允許的和不允許的。如果允許狀態轉換,繼續。如果不是,你會拋出一個異常,解釋爲什麼它不被允許。Aggregate-Root:State更改或失敗,異常或...?

但什麼是如果國有變化不會發生,因爲它是已經在請求國

例如,如果您的聚合根目錄上有Approve方法,並且在調用該方法時狀態已被批准?

  • 如果一個拋出異常一拉 「XYZ已經批准」?
  • 還是應該是默默忽略
  • 還是應該狀態變化再次「發信號」(事件採購,下一段)?

在我的情況下,我使用事件源,所以如果發生狀態改變,事件正在發射。在我的事件流中發生沒有真正狀態變化的事件並不會對我感覺「乾淨」,因爲我希望確信這些事件實際上是由於改變狀態的行爲而產生的。

有沒有經驗法則?

編輯:
在所描述的情況下批准認可的元素不會真的傷害。所以傾向於這種方式(謝謝@Eben Roux,@ guillaume31)。

但是,讓我們多一點香料添加到它(這個問題背後的實際問題):

假設:

  • 消息總線
  • 異步命令/事件處理
  • 一個進程管理器

如果進程管理器(aka saga)發出命令(異步)並想知道命令是否成功會怎麼樣?我認爲如果進程管理器不必關心關於這個實現細節,那麼減少精神負載/錯誤來源

我看到處理3種方式是:

  • 「命令ID爲ABC成功/失敗」總線
    流程管理器等待發送的消息,而不是事件的信息
  • 使命令執行同步
    如果流程管理器遭遇也不例外,一切都很好,繼續前行
  • 引入新的事件此事件ApprovalDeclined { WasAlreadyApproved = true }
    額外的過程管理器等待 - 磁偏角是集合歷史記錄,也許是有利的,也許根本不需要的部分...

我知道:「它取決於「
但你能想到任何其他(更優雅/更容易/不同)的解決方案嗎?處理這個問題最喜歡的「過程管理器兼容」方式是什麼?

回答

2

我不認爲這會有一個經驗法則。

消息idempotence當然是一件好事,所以簡單地忽略消息/狀態變化是或許是要走的路。

我不會再發信號,因爲沒有效果。

1

我想說這取決於你的域名。如果你想警告用戶他們正在批准已經批准的東西,那麼總會有一些反饋。它可能是一個例外as in Deactivate() here或由應用程序服務/命令處理程序中繼的返回值(注意這可能不是100%CQRS兼容)。

如果批准已經完成的事實對域任務來說並不重要,那麼您可以忽略該操作或再次執行該操作。

從用戶的角度來看,你將最有可能不允許反正重新覈準的東西,那麼,這種情況將是邊際的情況下:併發認證2個用戶,腳本,做「強力」審批等

+0

是的,+1取決於您的域名(或者,或者常識)。 – 2014-09-30 12:18:28

0

看來 - 對我來說 - 你很困惑應用程序和基礎設施級的問題。

應用程序級別涉及預期的域特定行爲。什麼是兩次批准的商業理由?爲什麼甚至會首先發生?也許這只是一個UI級別的併發事件,但是,爲什麼多個用戶在同一時間批准同一件事?也許他們尚未解決的業務層面存在問題。理解爲什麼第一是必不可少的。解決方案通常不在軟件本身中。

基礎架構級別涉及諸如保證消息傳遞(例如至少一次或恰好一次)的事情。當基礎設施無法兌現承諾時,這會如何影響業務(如果有的話)?它如何影響你的過程?無論如何,你的過程是什麼?再次,從領域特定的角度來看,推斷這些事情是非常重要的。在一天結束時,您可以採取風險或運營成本減輕措施。

在這種特殊情況下,問自己爲什麼以及如何在啓動批准命令之前將流程放到了哪裏(批准過程有點奇怪,通常由人工完成)。它怎麼沒有遵守以前的批准(記住,這個曾經聚集的東西已經被批准了)?你可以引入一個超時(作爲一個消息給它的(過程)未來的自我),但是在這種情況下做這件事似乎有點奇怪(我幾乎不知道該說什麼)。

不要採取這種錯誤的方式,但我認爲你需要深入挖掘領域特定的一面或共享更多的細節。

+0

我來回讀了你的回答,但我認爲它不符合我試圖找出的觀點 - 但仍然非常感激! (發展中的)問題不是關於消息傳遞 - 更重要的是:過程管理器如何知道它的命令成功 - 以一般方式?除了特定的情況 - 這只是一個(也許是壞的)例子 - 我仍然試圖在我已經完成時做了些什麼,我需要實現一個進程管理器(沒有ESB)... – 2014-11-04 22:59:07

+0

...這會影響聚合體處理這種無狀態變化 - 例外或無事件發射 - 傳遞的「規則」。要麼是:沒有aggregate-state-change => exception =>在其中帶有command-id的總線上的CommandFailed系統事件。 「失敗」,雖然總量處於合適的狀態?似乎錯了。或者:在總線上沒有發出event-message => CommandSucceeded系統事件,沒有聚合狀態改變=>命令「通過」。這對我來說最有意義,儘管現在進程管理器監聽系統事件,而不是「正常」事件......我只是在這個問題上尋找一些指導。 – 2014-11-04 23:16:31