有時候,相同穀粒的多個實例可以啟動,例如在操作多叢集並使用 OneInstancePerClusterAttribute時。
JournaledGrain
是設計來支援具有最小摩擦的復寫實例。 它依賴 記錄一致性提供者 來執行必要的通訊協定,以確保所有實例都同意相同的事件序列。 特別是,它會處理下列層面:
一致版本:所有版本的粒紋狀態(但暫定版本除外)都是以相同的全域事件序列為基礎。 特別是,如果兩個實例看到相同的版本號碼,它們就會看到相同的狀態。
賽車事件:多個實例可以同時引發事件。 一致性提供者會解析此競爭,並確保所有實例都同意相同的順序。
通知/重新活動:在一個粒紋實例引發事件之後,一致性提供者不僅會更新記憶體,也會通知所有其他粒紋實例。
如需一致性模型的一般討論,請參閱 我們的TechReport 和 GSP 檔 (全域序列通訊協定)。
條件式事件
賽車活動如果發生衝突可能會有問題,無論如何,兩者都不應有牽涉。 例如,從銀行帳戶提取資金時,兩個實體可能會獨立確認賬戶中有足夠的資金來進行取款,並觸發取款事件。 不過,這兩個事件的結合可能會導致帳戶透支。 若要避免這種情況, JournaledGrain
API 支援 RaiseConditionalEvent 方法。
bool success = await RaiseConditionalEvent(
new WithdrawalEvent() { /* ... */ });
條件式事件會仔細檢查本機版本是否符合記憶體中的版本。 如果沒有,這表示事件序列在此期間成長,表示此事件輸給另一個事件。 在這種情況下,條件式事件 不會 附加至記錄檔,RaiseConditionalEvent 並傳回 false
。
這類似於使用帶有條件存儲更新的電子標記,並提供簡單的機制來避免提交衝突的事件。
可以將條件式和無條件事件同時應用於同一個粒度,例如 DepositEvent
和 WithdrawalEvent
,這是合理且可行的。 存款不需要有條件:即使 DepositEvent
輸掉了比賽,也不必取消,但仍然可以附加至全域事件序列。
等候由 RaiseConditionalEvent
傳回的工作即可確認事件。您也不需要呼叫 ConfirmEvents
。
明確同步處理
有時候,您可能想要確保數據已經同步到最新版本。 您可以藉由呼叫下列項目來強制執行此作業:
await RefreshNow();
此呼叫會執行兩件事:
- 確認所有未確認的事件。
- 從記憶體載入最新版本。