KES資料庫實踐指南:探索KES資料庫的事務隔離級別

努力的小雨發表於2024-07-02

引言

前兩篇文章我們詳細講解了如何安裝KES金倉資料庫,並提供了快速查詢和搭建基於coze平臺的智慧體的解決方案。今天,我們的焦點將放在併發控制機制和事務隔離級別上。

本文將透過一系列實驗操作,深入探討KES資料庫中的併發控制機制和事務隔離級別。我們將透過實際操作演示,幫助讀者全面理解併發控制的重要性及其實施方法。

本章將直接基於實際操作進行演示。如果您還沒有成功安裝,請參考我之前提到的安裝指南文章:

金倉資料庫全攻略:簡化部署,最佳化管理的全流程指南

併發控制

併發控制的重要性

併發控制是資料庫管理系統中的一個核心概念,它確保在多使用者環境中,對資料庫的併發訪問不會破壞資料的完整性和一致性。

當多個使用者同時對資料庫進行讀寫操作時,如果缺乏有效的併發控制機制,可能會導致資料更新的競態條件,從而引發資料不一致的問題。例如,如果兩個事務同時增加同一賬戶的餘額,而沒有適當的鎖定機制,可能會導致餘額被錯誤地增加多次或一次都未增加。

因此,透過併發控制,資料庫能夠安全地處理多個事務,保證資料的準確性和可靠性。

併發控制與ACID原則

ACID原則是資料庫事務的四個基本屬性:原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)和永續性(Durability)。併發控制直接關聯到這些屬性的實現:

  • 原子性:確保事務中的所有操作要麼全部完成,要麼全部不完成,透過併發控制可以避免事務的部分執行對資料庫狀態的影響。
  • 一致性:保證事務執行的結果必須使資料庫從一個一致的狀態轉移到另一個一致的狀態,透過併發控制防止了違反業務規則的事務提交。
  • 隔離性:確保併發執行的事務之間不會互相影響,每個事務都像在獨立執行一樣,透過鎖機制和MVCC等併發控制技術實現。
  • 永續性:一旦事務提交,它對資料庫的改變就是永久性的,即使系統發生故障也不會丟失,透過併發控制確保在事務提交前資料已經正確寫入資料庫。

序列化與並行執行的權衡

序列化是最高的事務隔離級別,它透過序列化所有的事務,確保它們一個接一個地執行,從而避免了併發執行可能引起的問題。然而,序列化雖然能夠提供最嚴格的隔離性,但會大大降低系統的併發能力,導致效能瓶頸。

與此相對的是並行執行,它允許多個事務同時執行,從而提高資料庫的吞吐量和響應速度。但是,如果並行執行沒有得到適當的控制,可能會導致資料異常,如髒讀、不可重複讀和幻讀。

因此,資料庫系統需要在序列化和並行執行之間找到平衡點。這通常透過使用不同的隔離級別和併發控制技術來實現,例如:

  • 使用鎖機制來控制對資料的訪問,確保事務在修改資料時不會相互干擾。
  • 採用MVCC等技術,允許讀取操作不受寫入操作的影響,同時保持資料的一致性檢視。

透過這些技術,資料庫可以在保證ACID屬性的同時,提供較高的併發效能,滿足現代應用對高併發處理能力的需求。

事務隔離級別

上面提到的知識點已經是開發人員在備考面試時幾乎都會掌握的基本內容。接下來,我將透過實際操作金倉資料庫來回顧這些知識點。在這裡,我會總結另一個事務隔離級別,並討論在不同隔離級別下可能出現的髒讀、不可重複讀和幻讀現象。這樣可以更深入地理解它們對資料庫操作的影響。

序號 隔離級別 髒讀 不可重複讀 幻讀 序列化異常
1 Read Uncommitted 可能,在KES中不允許 可能 可能 可能
2 Read Committed 不可能 可能 可能 可能
3 Repeatable Read 不可能 不可能 可能,在KES中不允許 可能
4 Serializable 不可能 不可能 不可能 不可能

特別需要強調的是,在KES資料庫中,Read Uncommitted隔離級別下不允許出現髒讀現象,而Repeatable Read隔離級別則會防止幻讀的發生。既然這些情況已經被明確提出,我們有必要實際實施一下,以驗證這些說法是否屬實。

首先看下預設的事務級別:

image

有三種可以修改事務級別的方式。第一種是直接修改配置檔案;第二種是在當前會話中修改隔離級別;第三種是在當前事務中修改隔離級別。為了演示方便,我們選擇使用第三種方式。那麼,我們可以開始了。

髒讀(Dirty Read)

髒讀指的是一個事務讀取了另一個事務尚未提交的資料更改的現象。在KES資料庫中,預設的隔離級別通常為已提交讀,因此通常不會發生髒讀。然而,為了演示髒讀的情況,我們可以假設將隔離級別設定為讀未提交(Read Uncommitted)。這樣一來,一個事務可以讀取到另一個事務尚未提交的資料變更,導致可能出現不一致的讀取結果。

事務1 事務2 描述
修改資料,但未 COMMIT SELECT 讀取事務1未提交的資料 事務1由於某種原因被 ROLLBACK,事務2讀取了髒資料

當然,我們的KES資料庫目前並不支援這種操作,但這個想法確實很有前途。我們可以嘗試一下。首先,我們可以同時啟動這兩個事務。

事務1和2都操作:

begin TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

當事務1嘗試檢視資料時,並未發現任何相關記錄。

image

事務2插入一條資料:

image

事務1查詢一下,還是沒有,發現KES確實不存在髒讀的情況:

image

不可重複讀

它發生在一個事務讀取了某個資料項,然後在同一事務中再次嘗試讀取同一資料項時,如果另一個併發事務已經更新了這個資料項,那麼第一個事務將讀取到不同的值。

在不可重複讀的情況下,一個事務的讀取操作可能會得到不同的結果,即使這些讀取是在同一個事務的上下文中執行的。這違背了事務的隔離性原則,因為事務應該與其他併發事務的操作隔離開來。

事務1 事務2 描述
SELECT 根據條件讀取到某值 UPDATE 修改該值並 COMMIT 事務1再次讀取發現值變了(不可重複讀)

事務1

  • 開始事務,並讀取某個資料項。
  • 再次嘗試讀取同一資料項。
-- 事務1開始
begin TRANSACTION ISOLATION LEVEL READ committed;

-- 讀取賬戶的初始餘額
SELECT balance FROM accounts WHERE id = 1;

-- ... 事務1尚未提交 ...

-- 再次讀取賬戶餘額,期望得到相同的結果
SELECT balance FROM accounts WHERE id = 1;

效果如下:

image

事務2

  • 開始另一個事務,並更新相同的資料項。
  • 提交事務。
-- 事務2開始
begin TRANSACTION ISOLATION LEVEL READ committed;

-- 更新賬戶餘額
UPDATE accounts SET balance = balance + 100 WHERE id = 1;

-- 提交事務2的更改
COMMIT;

效果如下:

image

幻讀

幻讀發生在一個事務在讀取某個範圍內的記錄時,另一個事務插入了新的記錄,導致第一個事務重新讀取時,似乎出現了“幻影”記錄。

事務1 事務2 描述
SELECT 根據條件從庫中讀取資料 DELETE 刪除部分記錄並 COMMIT 事務1再次讀取發現某些記錄消失(幻讀情況A)
SELECT 根據條件從資料庫中讀取資料 INSERT 插入一些記錄並 COMMIT 事務1再次讀取發現多了一些記錄(幻讀情況B)

SQL示例

-- 事務1:選擇某個範圍內的記錄
begin transaction isolation level repeatable read ;
SELECT * FROM accounts WHERE id BETWEEN 1 AND 5;

-- 事務2:插入新的記錄
begin transaction isolation level repeatable read ;
INSERT INTO accounts (id, balance) VALUES (2, 1000);
COMMIT;

-- 事務1再次選擇,可能會看到新插入的記錄(幻讀)
SELECT * FROM accounts WHERE id BETWEEN 1 AND 6;
COMMIT;

當我們討論這個邏輯時,我們可以進行演示,因為官方KES文件表明,在可重複讀隔離級別下,正常情況下不會出現幻讀。這意味著我們可以驗證這一點。

插入演示-事務一

可以看到,在我們提交事務之前,無法看到已插入的記錄。因此,這次驗證表明,在KES中,即使在可重複讀隔離級別下,也已經成功地消除了幻讀現象。

image

插入演示-事務二

事務二的操作非常簡單,僅僅是在可重複讀隔離級別下建立了一條資料併成功提交了事務。

image

當然,讓我們進一步演示刪除操作,以確認在此操作中是否也能有效避免幻讀現象。

刪除演示-事務一

這裡我們同樣進行了演示,直接將隔離級別設定為可重複讀,並執行了查詢,但沒有提交事務。我們觀察到在操作過程中沒有出現任何變化,成功地避免了幻讀現象。

image

刪除演示-事務二

開啟後隔離級別後,執行了一個刪除操作,並將其提交給資料庫。

image

總結

本文深入探討了KES資料庫中的併發控制機制和事務隔離級別的重要性及實施方法。我們從併發控制的基本概念出發,詳細解釋了ACID原則如何透過不同的隔離級別得以實現,以及在序列化與並行執行之間的權衡取捨。透過實際操作和示例,我們展示了不同隔離級別下可能出現的髒讀、不可重複讀和幻讀現象,以及KES資料庫是如何應對這些問題的。

隨著現代應用對高併發處理能力需求的增加,正確理解並實施良好的併發控制策略變得尤為重要。透過本文的學習,讀者可以更好地理解如何透過合適的隔離級別和併發控制技術來平衡資料的一致性和效能需求,從而確保資料庫操作的準確性和可靠性。

在接下來的實際操作中,我們將繼續探索不同隔離級別的實際影響,驗證理論知識的應用,並進一步完善對資料庫管理與最佳化的理解。

好的,畢竟我不是DBA,所以我會繼續以DevOps的角度進行解析金倉資料庫。


我是努力的小雨,一名 Java 服務端碼農,潛心研究著 AI 技術的奧秘。我熱愛技術交流與分享,對開源社群充滿熱情。身兼掘金優秀作者、騰訊雲內容共創官、阿里雲專家博主、華為云云享專家等多重身份。

🚀 目前,我的探索重點在於 AI Agent 智慧體應用,我對其充滿好奇,並不斷探索著其潛力與可能性。如果你也對此領域充滿熱情,歡迎與我交流分享,讓我們共同探索未知的領域!

💡 我將不吝分享我在技術道路上的個人探索與經驗,希望能為你的學習與成長帶來一些啟發與幫助。

🌟 歡迎關注努力的小雨!🌟

相關文章