Share via


交易和開放式並行存取控制

適用於:NoSQL

資料庫交易提供安全且可預測的程式設計模型來處理並行的資料變更。 傳統關聯式資料庫 (例如 SQL Server) 可讓您使用預存程序和/或觸發程序撰寫商務邏輯,將其傳送至伺服器,以直接在資料庫引擎內執行。 使用傳統的關聯式資料庫時,您需要處理兩個不同的程式設計語言:(非交易式) 應用程式程式設計語言 (例如 JavaScript、Python、C#、Java 等等),以及資料庫原生執行的交易式程式設計語言 (例如 T-SQL)。

Azure Cosmos DB 中的資料庫引擎支援與 ACID (不可部分完成性、一致性、隔離性、耐用性) 完全相容的交易與快照集隔離。 容器邏輯分割區範圍內的所有資料庫作業,都會在由分割區複本裝載的資料庫引擎內以交易方式執行。 這些作業包括寫入 (更新邏輯分割區內的一或多個項目) 和讀取作業。 下表說明不同的作業與交易類型:

運算 作業類型 單一或多項目交易
插入 (不含觸發程序前/觸發程序後) 寫入 單一項目交易
插入 (含觸發程序前/觸發程序後) 寫入和讀取 多項目交易
取代 (不含觸發程序前/觸發程序後) 寫入 單一項目交易
取代 (含觸發程序前/觸發程序後) 寫入和讀取 多項目交易
更新插入 (不含觸發程序前/觸發程序後) 寫入 單一項目交易
更新插入 (含觸發程序前/觸發程序後) 寫入和讀取 多項目交易
刪除 (不含觸發程序前/觸發程序後) 寫入 單一項目交易
刪除 (含觸發程序前/觸發程序後) 寫入和讀取 多項目交易
執行預存程序 寫入和讀取 多項目交易
系統已啟動執行合併程序 寫入 多項目交易
系統已啟動執行根據項目的到期 (TTL) 刪除項目 寫入 多項目交易
讀取 讀取 單一項目交易
變更摘要 參閱 多項目交易
編頁報表 參閱 多項目交易
編頁報表 參閱 多項目交易
在執行分頁查詢時執行 UDF 參閱 多項目交易

多項目交易

Azure Cosmos DB 可讓您以 JavaScript 寫入預存程序、觸發程序前/觸發程序後、使用者定義函式 (UDF),以及合併程序。 Azure Cosmos DB 原生支援在其資料庫引擎內部執行 JavaScript。 您可以在容器中註冊預存程序、觸發程序前/觸發程序後、使用者定義函式 (UDF) 和合併程序,並在之後於 Azure Cosmos DB 資料庫引擎內以交易方式執行。 以 JavaScript 撰寫應用程式邏輯可允許在資料庫交易內,以自然方式表達控制流程、變數範圍、指派,以及整合例外狀況處理基本項目。

JavaScript 型預存程序、觸發程序、UDF,以及合併程序,都包裝在環境 ACID 交易內,且快照集會在邏輯分割區內跨所有項目隔離。 在執行期間,如果 JavaScript 程式擲回例外狀況,會中止整個交易並回復。 產生的程式設計模型非常簡單,但功能強大。 JavaScript 開發人員會取得「持續性」程式設計模型,同時仍然使用其熟悉的語言建構和程式庫基本。

直接在資料庫引擎內執行 JavaScript 的能力,可對容器的項目提供資料庫作業的具效能和交易式執行。 此外,由於 Azure Cosmos DB 資料庫引擎原生支援 JSON 和 JavaScript,因此應用程式與資料庫的類型系統之間沒有阻抗不相符的問題。

樂觀並行控制

開放式並行存取控制可讓您避免遺失更新和刪除。 並行、衝突的作業會受制於擁有項目之邏輯分割區所裝載的資料庫引擎所受到的一般封閉式鎖定限制。 當兩個並行作業嘗試更新邏輯分割區內某個項目的最新版本時,它們其中之一將會成功,另一個則會失敗。 但是,如果嘗試並行更新相同項目的一或兩個作業之前已讀取該項目的較舊版本時,資料庫不會知道兩個衝突作業的其中之一或兩者之前所讀取的值是否確實為項目的最新值。 幸好可以使用開放式並行存取控制 (OCC) 先偵測此情況,再讓兩個作業在資料庫引擎內部輸入交易界限。 OCC 會保護您的資料,避免意外遭到其他人覆寫。 它也能防止其他人不小心覆寫您自己所做的變更。

使用 ETag 和 HTTP 標頭實作開放式同步存取控制項

Azure Cosmos DB 容器中儲存的每個項目都有系統定義的 _etag 屬性。 _etag 的值會自動產生,並在項目每次更新時,由伺服器更新。 _etag 可以和用戶端提供的 if-match 要求標頭搭配使用,以允許伺服器決定是否可以有條件地更新項目。 if-match 標頭的值與伺服器中 _etag 的值相符時,項目就會更新。 如果 if-match 要求標頭的值不再是最新狀態,伺服器會拒絕該作業,並提供「HTTP 412 前置條件失敗」回應訊息。 然後用戶端可以重新擷取項目,以取得項目在伺服器上的最新版本,或用項目自己的 _etag 值覆寫伺服器中的項目版本。 此外,_etag 可以與 if-none-match 標頭搭配使用,以判斷是否需要重新擷取資源。

項目的 _etag 值會在項目每次更新時變更。 取對於代項目作業,必須在要求選項中明確表示 if-match。 如需範例,請參閱 GitHub 中的範例程式碼。 預存程序接觸過的所有寫入項目,系統都會以隱含方式檢查其 _etag 值。 如果偵測到任何衝突,預存程序將會復原交易,並擲回例外狀況。 透過此方法,在預存程序內的所有寫入都會自動套用,或全部不會自動套用。 這是應用程式重新套用更新並重試原始用戶端要求的信號。

開放式同步存取控制項和全域散發

Azure Cosmos DB 的通訊通訊協定層項目的並行更新受制於 OCC。 針對專為單一區域寫入設定的 Azure Cosmos DB 帳戶,Azure Cosmos DB 可確保您正在更新 (或刪除) 之項目的用戶端版本和 Azure Cosmos DB 容器中項目的版本相同。 這可確保您寫入的內容會受到保護,防止因為其他人寫入而意外遭到覆寫,反之亦然。 在多使用者環境中,開放式並行存取控制可防止您不小心刪除項目,或更新項目的錯誤版本。 因此,項目會收到保護,不會受到惡名昭彰的「遺失更新」或「遺失刪除」問題影響。

在設定多區域寫入的 Azure Cosmos DB 帳戶中,如果資料的 _etag 符合本機區域中的資料,則可以獨立地將資料認可到次要區域。 一旦新的資料在次要區域的本機中認可之後,就會合並到中樞或主要區域中。 如果衝突解決原則將新的資料合併到中樞區域,則會使用新的 _etag 來全域複寫此資料。 如果衝突解決原則拒絕新的資料,次要區域將會回復成原始資料和 _etag

下一步

深入了解下列文章中描述的資料庫交易和開放式並行存取控制: