Share via


複寫的粒紋

有時候,相同粒紋可能會有多個執行個體處於作用中狀態,例如,在操作多叢集時,以及使用 OneInstancePerClusterAttribute 時。 JournaledGrain 的用意是要以最小的阻礙支援複寫的執行個體。 它採用記錄一致性提供者來執行必要的通訊協定,以確保所有執行個體都同意相同的事件序列。 特別是,它會關注以下幾方面:

  • 一致的版本:粒紋狀態的所有版本 (暫訂版本除外) 均以相同的全域事件序列為基礎。 特別是,如果兩個執行個體顯示相同的版本號碼,則會顯示相同的狀態。

  • 競爭事件:多個執行個體可以同時引發事件。 一致性提供者可以解決此競爭,並確保每個人都同意相同的序列。

  • 通知/反應性:在一個粒紋執行個體引發事件後,一致性提供者不僅會更新儲存體,也會通知所有其他的粒紋執行個體。

如需一致性模型的一般討論,請參閱我們的 TechReportGSP 文件 (全域序列通訊協定)。

條件式事件

競爭事件若有衝突則可能形成問題,也就是說,基於某種原因不應兩者都認可。 例如,從銀行帳戶領錢時,兩個執行個體可能會獨立判斷有足夠的資金可供領取,並發出領款事件。 但是這兩個事件的組合可能會導致透支。 為了避免這種情況,JournaledGrain API 支援 RaiseConditionalEvent 方法。

bool success = await RaiseConditionalEvent(
    new WithdrawalEvent() { /* ... */ });

條件式事件會詳細檢查本機版本是否符合儲存體中的版本。 若不符合,表示事件序列在此期間也已增長,即此事件已輸掉與其他事件的競爭。 在此情況下,條件式事件不會附加至記錄,而 RaiseConditionalEvent 會傳回 false。

這類似於將 e-Tag 用於條件式儲存體更新,且同樣會提供簡單的機制來避免認可衝突的事件。

對相同的粒紋同時使用條件式和無條件事件是可行的且合理的,例如 DepositEventWithdrawalEvent。 存款不需要有條件:即使 DepositEvent 輸掉競爭,也不需要取消,但仍可附加至全域事件序列。

等候 RaiseConditionalEvent 傳回的工作即足以確認事件,也就是說,不需要同時呼叫 ConfirmEvents

明確同步處理

在某些情況下,應確保粒紋會完全符合最新版本。 呼叫下列命令可強制執行此動作:

await RefreshNow();

這會執行兩項作業︰

  1. 確認所有未確認的事件。
  2. 從儲存體載入最新版本。