交易可序列化和隔離

本頁說明交易資料爭用、可序列化能力和隔離。如需交易程式碼範例,請改為參閱交易和批次寫入相關說明。

交易與資料爭用

為了讓交易成功,由其讀取作業擷取的文件必須保持為交易外的作業未修改。若其他作業嘗試變更其中一份文件,這項作業會在交易中進入資料爭用狀態。

資料爭用
兩個以上的作業互相競爭控制同一份文件時。例如,單一交易可能需要文件保持一致性,而並行作業則會嘗試更新該文件的欄位值。

Cloud Firestore 會延遲或失敗其中一項作業,藉此解決資料爭用問題。Cloud Firestore 用戶端程式庫會自動重試因資料爭用而失敗的交易。在重試次數有限後,交易作業會失敗並傳回錯誤訊息:

ABORTED: Too much contention on these documents. Please try again.

在決定要失敗或延遲的作業時,行為則視用戶端程式庫的類型而定。

  • 行動/網頁 SDK 會使用樂觀並行控制項。

  • 伺服器用戶端程式庫會使用惡意並行控制。

行動/網頁 SDK 中的資料爭用

行動/網頁 SDK (Apple 平台、Android、Web、C++) 會使用樂觀並行控制項來解決資料爭用情形。

最佳化並行控管機制
根據以下假設:資料爭用不太可能或對資料庫鎖定不太有效率的假設。最佳化交易不使用資料庫鎖定來阻止其他作業變更資料。

行動/網頁 SDK 使用樂觀並行控制項,因為這類 SDK 可在具有高延遲和不穩定的網路連線環境中運作。在高延遲環境中鎖定文件會導致過多資料爭用失敗。

在 Mobile/Web SDK 中,交易會追蹤您在交易中讀取的所有文件。只有在交易執行期間沒有任何文件變更時,交易才會完成其寫入作業。如果有任何文件變更,交易處理常式會重試交易。如果交易在重試數次後仍未取得簡潔結果,表示交易因資料爭用而失敗。

伺服器用戶端程式庫中的資料爭用

伺服器用戶端程式庫 (C#、Go、Java、Node.js、PHP、Python、Ruby) 會使用慣用並行控制來解決資料爭用情況。

悲觀並行控制
根據以下假設:資料爭用可能會發生的情況。悲觀交易會使用資料庫鎖定,避免其他作業修改資料。

伺服器用戶端程式庫會使用惡意並行控制,因為它可以降低延遲時間,以及連線至資料庫的穩定連線。

在伺服器用戶端程式庫中,交易會鎖定讀取的文件。文件上的交易鎖定會封鎖該文件的其他交易、批次寫入和非交易寫入。交易會在修訂時釋放文件鎖定。如果因任何原因逾時或失敗,也會釋放鎖定。

當交易鎖定文件時,其他寫入作業必須等候交易解除鎖定。交易會依照時間順序取得鎖定。

可序列化隔離

交易之間的資料爭用與資料庫隔離層級密切相關。資料庫的隔離等級說明瞭系統處理並行作業之間衝突的方式。衝突源自以下資料庫要求:

  • 交易需要準確且一致的資料。
  • 為了有效率地使用資源,資料庫會並行執行作業。

在隔離等級低的系統中,交易內的讀取作業可能會從並行作業中的未修訂變更讀取不正確的資料。

可序列化隔離定義最高隔離等級。「可序列化」隔離意味著:

  • 您可以假設資料庫會連續執行交易。
  • 並行作業中的未修訂變更不會影響交易。

即使資料庫平行執行多項交易,這項保證也必須保留。資料庫必須實作並行控管機制,才能解決導致這項保證中斷的衝突。

Cloud Firestore 保證可序列化隔離交易。Cloud Firestore 中的交易會序列化,並依照修訂時間隔離。

可序列化隔離 (依修訂版本)

Cloud Firestore 會為每筆交易指派一個修訂時間,代表單一時間點。當 Cloud Firestore 修訂交易對資料庫進行的變更時,您可以假設交易內的所有讀取和寫入作業確切在修訂時間發生。

實際執行交易需要一段時間。交易會在修訂時間之前開始,且多項作業的執行作業可能會重疊。Cloud Firestore 維持可序列化隔離 並確保達成以下目標:

  • Cloud Firestore 會按照修訂時間依序修訂交易。
  • Cloud Firestore 會使用較晚的修訂時間,將交易與並行作業區隔開來。

如果並行作業之間發生資料爭用情形,Cloud Firestore 會使用樂觀和悲觀並行控管機制來解決爭用情況。

在交易中隔離

交易隔離也適用於交易中的寫入作業。交易內的查詢和讀取不會看到先前在該交易中寫入的結果。即使您在交易中修改或刪除文件,所有在交易中讀取的文件都會在交易的寫入作業之前,於修訂時傳回文件版本。如果文件不存在,讀取作業不會傳回任何結果。

資料爭用問題

如要進一步瞭解資料爭用情形和解決方式,請參閱疑難排解頁面