天天看點

資料庫隔離級别詳解

事務(transaction)是資料庫管理系統的執行機關,可以是一個資料庫操作(如Select操作)或者是一組操作序列。事務ACID屬性,即原子性(Atomicity)、一緻性(Consistency)、隔離性(Isolation)、持久性(Durability)。

原子性:保證事務中的所有操作全部執行或全部不執行。例如執行轉賬事務,要麼轉賬成功,要麼失敗。成功,則金額從轉出帳戶轉入到目的帳戶,并且兩個帳戶金額将發生相應的變化;失敗,則兩個賬戶的金額都不變。不會出現轉出帳戶扣了錢,而目的帳戶沒有收到錢的情況。

一緻性:保證資料庫始終保持資料的一緻性——事務操作之前是一緻的,事務操作之後也是一緻的,不管事務成功與否。如上面的例子,轉賬之前和之後資料庫都保持資料上的一緻性。

隔 離性:多個事務并發執行的話,結果應該與多個事務串行執行效果是一樣的。顯然最簡單的隔離就是将所有事務都串行執行:先來先執行,一個事務執行完了才允許 執行下一個。但這樣資料庫的效率低下,如:兩個不同的事務隻是讀取同一批資料,這樣完全可以并發進行。為了控制并發執行的效果就有了不同的隔離級别。下面 将詳細介紹。

持久性:持久性表示事物操作完成之後,對資料庫的影響是持久的,即使資料庫因故障而受到破壞,資料庫也應該能夠恢複。通常的實作方式是采用日志。

事務隔離級别(transaction isolation levels):隔離級别就是對對事務并發控制的等級。ANSI/ ISO SQL将其分為串行化(SERIALIZABLE)、可重複讀(REPEATABLE READ)、讀已送出(READ COMMITED)、讀未送出(READ UNCOMMITED)四個等級。為了實作隔離級别通常資料庫采用鎖(Lock)。一般在程式設計的時候隻需要設定隔離等級,至于具體采用什麼鎖則由資料庫來設定。首先介紹四種等級,然後舉例解釋後面三個等級(可重複讀、讀已送出、讀未送出)中會出現的并發問題。

串行化(SERIALIZABLE):所有事務都一個接一個地串行執行,這樣可以避免幻讀(phantom reads)。對于基于鎖來實作并發控制的資料庫來說,串行化要求在執行範圍查詢(如選取年齡在10到30之間的使用者)的時候,需要擷取範圍鎖(range lock)。如果不是基于鎖實作并發控制的資料庫,則檢查到有違反串行操作的事務時,需要滾回該事務。

可重複讀(REPEATABLE READ):所有被Select擷取的資料都不能被修改,這樣就可以避免一個事務前後讀取資料不一緻的情況。但是卻沒有辦法控制幻讀,因為這個時候其他事務不能更改所選的資料,但是可以增加資料,因為前一個事務沒有範圍鎖。

讀已送出(READ COMMITED):被讀取的資料可以被其他事務修改。這樣就可能導緻不可重複讀。也就是說,事務的讀取資料的時候擷取讀鎖,但是讀完之後立即釋放(不需要等到事務結束),而寫鎖則是事務送出之後才釋放。釋放讀鎖之後,就可能被其他事物修改資料。該等級也是SQL Server預設的隔離等級。

讀未送出(READ UNCOMMITED):這是最低的隔離等級,允許其他事務看到沒有送出的資料。這種等級會導緻髒讀(Dirty Read)。

 參考:

Isolation (database systems):http://en.wikipedia.org/wiki/Isolation_(computer_science)

繼續閱讀