5

Here是一篇很好的文章,它描述了什麼是ES以及如何處理它。EventSourcing競賽條件

那裏一切都很好,但有一個圖像困擾着我。這是

ES example

據我所知,在分佈式事件爲基礎的系統,我們能只能達到最終一致性。無論如何......我們如何確保我們不會預訂更多座位?如果有很多併發請求,這尤其是一個問題。

可能發生n個聚合填充相同數量的保留席位,並且所有這些聚合實例都允許預留。

+0

這只是簡單的樂觀鎖定... – plalx

回答

2

將會有幾種方法來處理這種情況。

首先,事件流將使當前版本成爲添加的最後一個事件的版本。這意味着,如果事件流在加載時不在版本中,那麼當您不應或不應該能夠保留事件流時。由於第一次寫入會導致事件流的版本增加,所以第二次寫入將不被允許。由於事件本身並不是排放的,而是事件採購的結果,因此我們在您的示例中不會出現競爭條件類型。

那麼,如果您的命令在隊列後面處理,則應該重試任何失敗。如果無法處理請求,您可以輸入正常的「我很抱歉,戴夫,我害怕我不能這樣做」的方案,讓用戶知道他們應該嘗試別的。

另一個選擇是通過針對某些錶行發佈更新來啓動處理,以序列化對聚合的任何調用。可能不是最優雅的,但它確實會導致整個系統範圍內的處理。

我想,在很大程度上,真的不可信當談到事務處理時,信任讀取存儲。

希望幫助:)

0

據我所知,在分配基於事件的系統,我們能夠既達到最終一致性,反正...如何不允許預訂更多的席位比我們有?特別是在許多併發請求方面?

所有事件對於運行它們的命令是私有的,直到記錄簿確認寫入成功爲止。所以我們根本不會分享這些事件,也不會在不知道我們版本的「接下來發生的事情」被記錄簿接受的情況下向調用者報告。

事件的寫入類似於聚合歷史記錄中尾指針的比較和交換。如果另一個命令在我們運行時改變了尾指針,我們的交換失敗了,我們必須減輕/重試/失敗。

在實踐中,這通常是通過讓寫入命令寫入記錄的預定位置來實現的。 (例如:GES中的ES-ExpectedVersion)。

如果預期的位置在錯誤的地方,預計記錄簿將拒絕寫入。將該位置視爲RDBMS中表格中的唯一鍵,並且您有正確的想法。

這意味着,有效,即寫入到事件流是實際上一致的 - 記錄的書只允許寫,如果你寫的位置是正確的,這意味着立場沒有改變,因爲您加載的歷史記錄的副本被寫入。

命令通常直接從記錄簿中讀取事件流,而不是最終一致的讀取模型。

雖然可能會發生n-AggregateRoots將被填充相同數量的保留位置,這意味着在保留方法中進行驗證將無濟於事。然後n-AggregateRoots將發出成功保留的事件。

每一個狀態位都需要一個聚合根監督。你可以有n個不同的副本運行,所有的副本都會競爭寫入相同的歷史記錄,但比較和交換操作只允許一個贏家,這確保了「該」聚合具有單個內部一致的歷史記錄。