真正的事務是可序列化的

2022-07-04 11:33:11 字數 2377 閱讀 2839

大多數資料庫都提供了事務隔離級別的選擇,可以在正確性和效能之間進行權衡。然而,高效能的代價就是開發人員必須小心研究事務互動否則就會引入一些微妙的錯誤。cockroachdb 預設提供了強隔離(serializable)可以確保你的應用總是看到期望的資料。在本文中我們將解釋這意味著什麼以及不充分的隔離在如何影響真實世界的應用。

sql標準定義四個隔離級別

serializable事務執行時好像在同一時刻僅有乙個事務執行;其他隔離級別允許出現sql標準稱作的「三種phenomena」髒讀、不可重複讀、幻讀。後續的研究(此處指critique,ivan在文章「分布式資料庫之事務隔離性」中已經進行了介紹)定義了額外的「phenomena」和隔離級別。

在現代研究中,這些「phenomena」更普遍被稱為「anomalies」,或者更直接稱為」lies」。當你使用乙個非serializable隔離級別時,你是在允許資料庫返回錯誤答案,希望它能比正確答案更快。sql標準認為這是危險的,需要serializable置為預設的隔離級別。更弱的隔離級別只是為那些可以容忍「anomalies」的應用提供了潛在的優化手段。

多數的資料庫忽略了將serializable作為預設隔離級別的規約,而是預設替換為更弱的rcrr隔離級別,它們的效能優先於安全性。更令人擔心的是,一些資料庫(包括oracle,postgresql v9.1以前)根本不提供serializable級別的事務隔離。oracle實現的serializable隔離級別實際上是更弱的「snapshot isolation」。snapshot isolation(快照隔離,簡稱si)的出現晚於sql標準的制定,但是已經被多種資料庫系統實現,因為它提供了很好的效能與一致性的平衡。它強於rc但弱於serializable,很類似rr但不完全等同(rr允許幻讀,但禁止寫偏序,si更好相反)。實現si的資料庫,在如何將其納入到四個sql標準隔離級別上有不同的選擇。oracle的選擇最激進,直接將他們的si實現稱為serializable。cockroachdb 和sql server則保守一些,將si作為獨立的第五個隔離級別。postgresql(9.1版本以後)介於兩者之間,使用si替換了rr。因為資料庫很少使用serializable模式,而是預設採用更弱的隔離級別,所以它通常很少經過徹底的測試和優化。例如postgresql有乙個固定大小的記憶體池,用來跟蹤可序列化事務間的衝突,但在高負載情況下會耗盡。

多數的資料庫廠商將更強的事務隔離作為給應用程式的乙個特殊選項用於應對額外的一致性需求。多數應用程式被認為可以執行在更快但是不安全的弱隔離模式下。這種處理問題的落後方式導致將應用程式暴露在大量細微的bug中。在cockroach labs,我們喜歡思考事務anomalies,以至於我們用它們來命名會議室。但我很難有信心的建議什麼時候選擇si替代serializable是安全有益的。

我們的哲學是從安全性出發向著高效能方向前進,這是比其他方式更優的。

斯坦福最近的研究展示了弱隔離性對真實世界的影響程度。 todd warszawski and peter bailis測試了12個電子商務應用程式並發現了22個事務相關的bug,其中5個在更高的隔離級別下可以避免。多數bug可以被簡單得利用並造成財務方面的影響。例如,在5個被測試的應用程式中,當操作乙個瀏覽器進行結算的同時,操作另乙個瀏覽器向購物車增加一項商品,可能導致新增的商品在賬單中免費。這些研究人員開發工具以半自動化的方式去確定這些脆弱點,為類似的更普遍的攻擊(研究者將其稱為acidrain 「酸雨」)鋪平了道路。

大多數預設弱隔離的資料庫都提供了解決方法,例如for updatelock in share mode(非標準語法)作為sql語句的修飾符。當正確使用時,即使在弱隔離級別下,這些修飾符也可以使事務安全。然而,這很容易出錯,而且即使是使用這些擴充套件方式,也會同時引入serializable模式大多數的缺點。(事實上,在rc事務中濫用select for update可以導致比serializable更差的效能,因為在那些序列化操作的地方可以僅使用共享鎖,卻使用了排他鎖) acidrain的研究顯示了這種技術的侷限性:3個應用程式中僅有乙個正確使用了select for update特性,其他兩個都存在漏洞。

mysql可序列化讀音 MySQL事務的可序列化

可序列化 serializable 事務的最高端別,在每個讀的資料行上,加上鎖,使之不可能相互衝突,因此,會導致大量的超時現象 設定b賬戶,事務的隔離級別 b賬戶,首先,將b賬戶的隔離級別設定為serializable 可以看出,b賬戶的事務隔離級別設定為了serializable b賬戶,開啟乙個...

可擴充套件的序列化協議

oceanbase的序列化協議是一種可擴充套件的協議,其基本單元為 乙個完整的資料報是形如下面的內容 例如 1 trans id 102 1024 cid 21 other abc 接收端解析方式 cpp bool more true while more www.2cto.com 通過這種方式,可...

可序列化和自定義序列化

序列化技術的主要兩個目的是 持久化儲存 按值封送。net framework支援三種序列化器 binary xml soap.他們各有優缺點,分別列如下 1.binary序列化是完全保真的,因為除非特殊宣告為nonserialized,那麼所有成員 包括私有的和公有的 都會被序列化。該序列化器的結果...