文章出處

回到目錄

當數據表被事務鎖定后,我們再進行select查詢時,需要為with(鎖選項)來查詢信息,如果不加,select將會被阻塞,直到鎖被釋放,下面介紹幾種SQL的鎖選項

SQL的幾把鎖

NOLOCK(不加鎖)

此選項被選中時,SQL Server 在讀取或修改數據時不加任何鎖。 在這種情況下,用戶有可能讀取到未完成事務(Uncommited Transaction)或回滾(Roll Back)中的數據, 即所謂的“臟數據”。 

HOLDLOCK(保持鎖)

此選項被選中時,SQL Server 會將此共享鎖保持至整個事務結束,而不會在途中釋放。 

UPDLOCK(修改鎖)

此選項被選中時,SQL Server 在讀取數據時使用修改鎖來代替共享鎖,并將此鎖保持至整個事務或命令結束。使用此選項能夠保證多個進程能同時讀取數據但只有該進程能修改數據。 

TABLOCK(表鎖)

此選項被選中時,SQL Server 將在整個表上置共享鎖直至該命令結束。 這個選項保證其他進程只能讀取而不能修改數據。 

PAGLOCK(頁鎖)

此選項為默認選項, 當被選中時,SQL Server 使用共享頁鎖。 

TABLOCKX(排它表鎖)

此選項被選中時,SQL Server 將在整個表上置排它鎖直至該命令或事務結束。這將防止其他進程讀取或修改表中的數據。

下面看一下.net frameworks平臺關于事務級別的枚舉,它對應于sql的事件級別

 

namespace System.Transactions
{
    // 摘要:
    //     Specifies the isolation level of a transaction.
    public enum IsolationLevel
    {
        // 摘要:序列化隔離級別,約束力最高,在數據集上放置一個范圍鎖,以防止其他用戶在事務完成之前更新數據集或將行插入數據集內。
     // 這是四個隔離級別中限制最大的級別。因為并發級別較低,所以應只在必要時才使用該選項。該選項的作用與在事務內所有 SELECT 語句中的所有表上設置 HOLDLOCK 相同。
// Volatile data can be read but not modified, and no new data can be added // during the transaction. Serializable = 0, // // 摘要:可重復讀的隔離級別,可能出現幻讀,鎖定查詢中使用的所有數據以防止其他用戶更新數據,但是其他用戶可以將新的幻像行插入數據集,
// 且幻像行包括在當前事務的后續讀取中。因為并發低于默認隔離級別,所以應只在必要時才使用該選項。
// Volatile data can be read but not modified during the transaction.New data // can be added during the transaction. RepeatableRead = 1, // // 摘要:不能讀但可修改,可能出現不可重復讀,指定在讀取數據時控制共享鎖以避免臟讀,但數據可在事務結束前更改,
// 從而產生不可重復讀取或幻像數據。該選項是 SQL Server 的默認值。
// Volatile data cannot be read during the transaction, but can be modified. ReadCommitted = 2, // // 摘要:可以讀也可以修改,可能出現臟數據,執行臟讀或 0 級隔離鎖定,這表示不發出共享鎖,也不接受排它鎖。
// 當設置該選項時,可以對數據執行未提交讀或臟讀;在事務結束前可以更改數據內的數值,行也可以出現在數據集中或從數據集消失。這是四個隔離級別中限制最小的級別。
// Volatile data can be read and modified during the transaction. ReadUncommitted = 3, // // 摘要:忽略數據的修改,得到修改前的數據 // Volatile data can be read.Before a transaction modifies data, it verifies // if another transaction has changed the data after it was initially read.If // the data has been updated, an error is raised.This allows a transaction to // get to the previously committed value of the data. Snapshot = 4, // // 摘要: // The pending changes from more highly isolated transactions cannot be overwritten. Chaos = 5, // // 摘要: // A different isolation level than the one specified is being used, but the // level cannot be determined.An exception is thrown if this value is set. Unspecified = 6, } }

 

對于事務級別的總結

下面是在嵌套事務中經常遇到的情況

  1  臟讀:一個事務會讀進還沒有被另一個事務提交的數據,所以你會看到一些最后被另一個事務回滾掉的數據。

  2  讀值不可復現:一個事務讀進一條記錄,另一個事務更改了這條記錄并提交完畢,這時候第一個事務再次讀這條記錄時,它已經改變了。

  3  幻影讀:一個事務用select子句來檢索一個表的數據,另一個事務insert一條新的記錄,并且符合select條件,這樣,第一個事務用同一個select條件來檢索數據后,就會多出一條記錄。

 

下面是IsolationLevel級別在使用過程中的一些說明(來自博文:http://www.cnblogs.com/CN5135/archive/2011/10/24/2222350.html)

ReadCommitted:
假設A事務對正在讀取數據Data放置了共享鎖,那么Data不能被其它事務改寫,所以當B事務對Data進行讀取時總和A讀取的Data數據是一致的,所以避免了臟讀。由于在A沒有提交之前可以對Data進行改寫,那么B讀取到的某個值可能會在其讀取后被A更改從而導致了該值不能被重復取得;或者當B再次用相同的where字句時得到了和前一次不一樣數據的結果集,也就是幻像數據。

ReadUncommitted:
假設A事務即不發布共享鎖,也不接受獨占鎖,那么并發的B或者其它事務可以改寫A事務讀取的數據,那么并發的C事務讀取到的數據的狀態和A的或者B的數據都可能不一致,那么。臟讀、不可重復讀、幻象數據都可能存在。

RepeatableRead:
(注意MSDN原文中的第一句話:在查詢中使用的所有數據上放置鎖,所以不存在臟讀的情況)。
假設A事務對讀取的所有數據Data放置了鎖,以阻止其它事務對Data的更改,在A沒有提交之前,新的并發事務讀取到的數據如果存在于Data中,那么該數據的狀態和A事務中的數據是一致的,從而避免了不可重復的讀取。但在A事務沒有結束之前,B事務可以插入新記錄到Data所在的表中,那么其它事務再次用相同的where字句查詢時,得到的結果數可能上一次的不一致,也就是幻像數據。

Serializable:
 在數據表上放置了排他鎖,以防止在事務完成之前由其他用戶更新行或向數據集中插入行,這是最嚴格的鎖。它防止了臟讀、不可重復讀取和幻象數據。

 

它的對應表如下:

隔離級別

臟讀(Dirty Read

不可重復讀(NonRepeatable Read

幻讀(Phantom Read

讀未提交(Read uncommitted)

可能

可能

可能

讀已提交(Read committed)

不可能

可能

可能

可重復讀(Repeatable read)

不可能

不可能

可能

可串行化(Serializable )

不可能

不可能

不可能

 

回到目錄


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


全站熱搜
創作者介紹
創作者 大師兄 的頭像
大師兄

IT工程師數位筆記本

大師兄 發表在 痞客邦 留言(0) 人氣()