DDD聚合:樂觀併發 -James Hickey

banq發表於2020-05-09

當系統的多個使用者嘗試在“相同”時間對同一塊資料進行操作時,會發生什麼情況?誰贏?誰輸了?本文將說明如何解決此類問題!
協作領域是可以同時由多個使用者/客戶端更改資源的領域,這要求對我們的業務邏輯進行更智慧的處理。
解決此問題的最流行方法之一是使用併發控制元件。換句話說,當資料不同步時,一種阻止這些併發寫入資料庫的方法。

悲觀併發
一種方法是使用悲觀併發。這是當我們鎖定整個資源並且在任何時候僅允許一個操作被訪問時。
有點像開啟excel時,現在網路驅動器上沒有其他人可以修改它了。
但是,這會導致效能不佳,並且從某種意義上講是天真的,因為我們只是“蠻力”鎖定所有內容。

樂觀併發

樂觀併發在某種程度上更加智慧和靈活。它還允許一些有趣的故障模式。
透過允許每個操作獲取資料儲存區的當前版本來工作。它可能是關聯式資料庫,文件或事件溯源。沒關係
然後,只要有聚合寫回,就針對資料儲存測試其版本,如果版本不同步(即在執行此操作時其他人已將其寫入儲存),那麼我們將使操作失敗。
這提供了一種有趣的故障模式,在該模式下,可以僅重試失敗的操作。只要資料儲存中有更新,它的操作仍然有意義。

如何實施?
例如,事件儲存具有此內建功能
例如,.NET客戶端中的一種寫入方法如下所示:

Task<WriteResult> AppendToStreamAsync(string stream, long expectedVersion, params EventData[] events)


第二個引數是告訴事件儲存您期望的版本的位置。如果不是那個版本,如上面的示例,那麼事件儲存將告訴您。
在關聯式資料庫中,您可以執行以下操作:

UPDATE sometable T
SET something = @someDataParam
WHERE T.RowVersion = @expectedRowVersionParam


根據您的資料庫引擎,這將返回受影響的行數。如果沒有影響,那麼您就知道在另一個操作“事務失敗”之前,另一個操作已寫入資料儲存。
 

相關文章