資料庫事務的特性與隔離級別

事務

    事務簡單的理解就是要在資料庫上執行的一組業務相關的SQL語句,是關係型資料庫的最基礎執行單位;但不是每個資料庫的每個引擎都支援事務,例如我們使用的MySQL資料庫的MyISAM就不支援事務。

ACID-資料庫事務的四大特性

    A-Atomicity(原子性)

    指資料庫事務的操作要麼全部執行,要麼全部不執行,也就是說事務的操作是原子性的,具有不可分割的特性;

    C-Consistency(一致性)

    指資料庫在事務操作前後都保持了一致性狀態,即事務操作前後資料庫只是從一種一致性狀態轉變為另一種一致性狀態;

    I-Isolation(隔離性)

    指資料庫允許多個併發事務同時對其資料進行讀寫和修改的能力,隔離性可以防止多個事務併發執行時由於交叉執行而導致數      據的不一致。事務隔離分為不同級別,包括讀未提交(Read uncommitted)、讀提交(read committed)、可重複讀(repeatable read)和序列化(Serializable)。;

    D-Durability(永續性)

    指資料庫事務處理結束後,對資料的修改就是永久的,即便系統故障也不會丟失。

以上四個特性基本描述了事務在執行前執行時以及執行後的特性。

MySQL資料庫事務的相關操作

1.檢視MySQL資料庫當前的引擎以及是否支援事務

    登陸資料庫後輸入show engines;

從圖中可以看出MySQL預設的引擎是InnoDB,該資料庫引擎支援事務和行級鎖以及外來鍵和儲存點等。

2.檢視當前資料庫事務的隔離級別

 在資料庫命令列輸入:select @@tx_isolation;

當前的事務隔離級別是可重複讀 REPEATABLE-READ。

3.設定資料庫事務隔離級別

也可以是

4.InnoDB的事務隔離級別分類

READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ和SERIALIZABLE

5.事務處理語句

    如果當前的引擎不支援資料庫事務,需要設定引擎為支援資料庫事務的InnoDB,MySQL預設的引擎是InnoDB,所以一般不需要修改引擎。預設的事務隔離級別是REPEATABLE READ,也不需要修改,如果不滿足對要求可以進行重新設定。在設定完隔離級別後可以開啟事務,開啟事務的方式是begin命令或者start transaction命令,提交事務是commit命令,事務回滾是rollback命令;也可以通過設定變數autocommit變數來處理事務,比如設定autocommit為1來達到事務的自動提交,如果autocommit為0則需要手段提交。

    儲存點,是對資料庫事務的細粒度管理,在一個數據庫是事務中可以有多個儲存點,每個儲存點有對應的id,事務回滾的時候可以指定回滾的儲存點,也可以刪除儲存點。Savepoint identifier  設定事務儲存點;RELEASE SAVEPOINT identifier;刪除事務儲存點;ROLLBACK TO identifier;把事務回滾到標記點。

資料庫髒讀,不可重複讀,幻讀(虛讀)與事務隔離級別

1.髒讀

    資料庫事務併發處理時,事務A對錶中的某行記錄進行了操作,此時事務B對該記錄進行了查詢,之後A事務進行了回滾操作,那麼B事務剛才讀取資料就是髒讀,所以髒讀就是並行事務間讀取了尚未提交的資料。

2.不可重複讀

    資料庫事務併發處理時,事務A對錶中的某記錄進行了讀取,接著事務B對事務進行修改並提交了,之後事務A對該記錄再次進行讀取,發現與之前讀取的結果不相同,儘管多次再讀取還是和之前讀取的結果不相同,這就是不可重複讀。不可重複讀和髒讀的區別在與前者讀取的是未提交的資料,後者讀取了已提交的資料。

3.幻讀(虛讀)

    資料庫事務併發處理時,事務A對某表中的記錄進行了條件統計,例如條件是名字中帶"中"字的,就在事務A統計期間,某條符合條件的記錄被事務B修改了,事務A再次進行統計時發現統計結果與上次不同,這就是幻讀也叫虛讀。幻讀與不可重複讀的區別在於前者是對於多條記錄的操作時因為另外一個事務的介入導致整體的結果異常,而後者是對同一條記錄的讀取,所以兩者的區別主要是在數量上的區別。

4.資料庫模擬演示

4.1 髒讀模擬

在兩個資料庫客戶端中模擬髒讀現象(兩個客戶端AB模擬事務AB,事務隔離級別是uncomiited,預設都已開啟事務):

   A客戶端對user表中的資料進行查詢,結果如圖:

B客戶端對user表中使用者名稱為rose的記錄更新年齡為16:

此時在A客戶端中查詢所有的user,發現名為rose的user年齡為16:

B客戶端現在進行事務回滾:

A客戶端再次進行檢視,發現名為rose的使用者年齡為12歲不是16歲:

4.2 不可重複讀模擬

在兩個資料庫客戶端中模擬不可重複讀現象(兩個客戶端AB模擬事務AB,事務隔離級別是uncomiited,預設都已開啟事務):

A客戶端對user表中的名為rose的user進行查詢:

B客戶端對該記錄進行了修改,將其age改為16,並提交。

A客戶端再對該記錄進行查詢,發現第一次之後查詢的結果和第一次不重複。

4.3幻讀(虛讀)模擬

在兩個資料庫客戶端中模擬幻讀現象(兩個客戶端AB模擬事務AB,事務隔離級別是uncomiited,預設都已開啟事務):

A客戶端統計所有的記錄數:

此時B客戶端刪除了其中一條記錄:

A客戶端再次查詢發現記錄數與之前的不相符

事務隔離級別

  髒讀 不可重複讀 幻讀

Read uncommitted 

可能出現 可能出現 可能出現

Read committed

不可能出現 可能出現 可能出現

Repeatable read

不可能出現 不可能出現 可能出現

Serializable

不可能出現 不可能出現 不可能出現

    上述的四個隔離級別是ISO/ANSI SQL92定義的,但是不是每個資料庫都完全實現了,但是MySQL是完全實現了的。那麼是資料庫事務隔離的實現是怎樣的呢?其實是資料庫索,MySQL中會有行級鎖和表鎖以及間隙鎖,InnoDB的行級鎖其實是索引加鎖,例如避免不可重複讀時,可以對該記錄進行鎖定,避免幻讀時可以對全表進行加鎖也就是使用表鎖。更加詳細的學習將會後續進行!