1. 程式人生 > >資料庫事務和鎖機制

資料庫事務和鎖機制

前幾日有一個獵頭公司的面試,其中問道我事務隔離這塊的知識點,猛一問真是想不起來啊,頓感羞愧啊,回來專門總結一下這方面的知識來夯實一下之前的知識體系,也提醒廣大園友們進步在於總結啊,好多不用的知識點,有時候有必要溫故知新啊。

簡介   

      ACID,是指在可靠資料庫管理系統(DBMS)中,事務(transaction)所應該具有的四個特性:原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、永續性(Durability).這是可靠資料庫所應具備的幾個特性.

     我們通過SQL SERVER對資料庫進行管理,不可避免要實現多個程序訪問資料庫同一資料,或者修改同一資料。 這樣就不得不提到SQL Server利用加鎖和阻塞來保證事務之間不同等級的隔離性,從而實現事務的互不干擾的訪問和操作資料庫。

     首先我們要知道都有哪些干擾會影響資料的隔離性:

     1、更新丟失(lost update):當系統允許兩個事務同時更新同一資料是,發生更新丟失。

     2、髒讀(dirty read):當一個事務讀取另一個事務尚未提交的修改時,產生髒讀。

      舉例說明什麼是髒讀:

1  23

通過以上三個圖不難發現,當事務1去插入一條資料,然後圖二去讀取被插入資料的表,此時事務1還沒有commit結果查詢結果直接將記憶體中的髒資料讀取出來,再Read Uncommitted 這個級別下,會出現髒讀,一旦資料未提交或者未提交成功則讀取資料是髒讀錯誤資料。

     3、非重複讀(nonrepeatableread):同一查詢在同一事務中多次進行,由於其他提交事務所做的修改或刪除,每次返回不同的結果集,此時發生非重複讀。

      舉例說明:

      123

以上三圖可以清楚表示出,在一個事務中,兩個查詢對同一個表,而再事務兩次查詢中發生了一次資料更新,導致事務中兩次查詢的結果不同。這就是所謂的nonrepeatableread。

     4、幻像(phantom read):同一查詢在同一事務中多次進行,由於其他提交事務所做的插入操作,每次返回不同的結果集,此時發生幻像讀。

    QQ截圖20150521162827

在標準SQL規範中,定義了4個事務隔離級別,不同的隔離級別對事務的處理不同:

◆未授權讀取(Read Uncommitted):允許髒讀取,但不允許更新丟失。如果一個事務已經開始寫資料,則另外一個事務則不允許同時進行寫操作,但允許其他事務讀此行資料。該隔離級別可以通過“排他寫鎖”實現。

◆授權讀取(Read Committed):允許不可重複讀取,但不允許髒讀取。這可以通過“瞬間共享讀鎖”和“排他寫鎖”實現。讀取資料的事務允許其他事務繼續訪問該行資料,但是未提交的寫事務將會禁止其他事務訪問該行。

◆可重複讀取(Repeatable Read):禁止不可重複讀取和髒讀取,但是有時可能出現幻影資料。這可以通過“共享讀鎖”和“排他寫鎖”實現。讀取資料的事務將會禁止寫事務(但允許讀事務),寫事務則禁止任何其他事務。

◆序列化(Serializable):提供嚴格的事務隔離。它要求事務序列化執行,事務只能一個接著一個地執行,但不能併發執行。如果僅僅通過“行級鎖”是無法實現事務序列化的,必須通過其他機制保證新插入的資料不會被剛執行查詢操作的事務訪問到。

   QQ截圖20150521165334

最後附上設定隔離級別的語法(老是記不清楚):

SET TRANSACTION ISOLATION LEVEL 
{

READ UNCOMMITTED

| READ COMMITTED

| REPEATABLE READ

| SERIALIZABLE

}

總結

     通過全篇的講述,我們也能清晰的理順一條思路,隔離級別越高,越能保證資料的完整性和一致性,但是對併發效能的影響也越大。對於多數應用程式,可以優先考慮把資料庫系統的隔離級別設為Read Committed,它能夠避免髒讀取,而且具有較好的併發效能。儘管它會導致不可重複讀、虛讀和第二類丟失更新這些併發問題,在可能出現這類問題的個別場合,可以由應用程式採用悲觀鎖或樂觀鎖來控制。