Sql Server鎖總結

來源:互聯網
上載者:User

 

MSSQL 並發控制小結

 

並行作業中容易出現的問題:

1.       更新丟失

a)         資料庫中的原值是200,A使用者在一個事務裡將其更新為300,同時B使用者在一個事務裡將其更新為400,但是B事務因為一些原因導致事務rollback了,當AB執行完後,資料庫中的值仍為200,這樣A的更新就丟失了

2.       髒讀

a)         資料庫中的原值為200,A使用者在一個事務裡將其更新為300,在該事務還沒有Commit & rollback之前,B使用者會讀到300,如果後來A事務rollback了,這樣B就出現了髒讀。

3.       不可重複讀取

a)         資料庫中的原值為200, A使用者在一個事務裡,第一次select時,結果為200,緊接著B使用者在另一個事務中更新為300,然後當A再做select操作,結果就不再是200,而是300,這就出現了同一事務中對同一行資料的兩次select結果不一致,該行資料就為不可重複讀取。

4.       虛讀

a)         資料庫中值大於200的行數原來有10行,A使用者在一個事務裡,第一次select後,結果為10行,緊接著B使用者在另一個事務中insert了一條新資料,如300,然後當A再做select操作,結果就不再是10,而是11,新增的那行資料就為虛讀。

為解決這些問題,而生的隔離等級:

1.       末授權讀取

a)         隔離等級最低,不允許丟失更新

b)         允許多個事務同時讀資料,但不允許多個事務同時寫資料

2.       授權讀取

a)         不允許髒讀,也不允許丟失更新

b)         事務中已經修改的行,在沒提交事務之前,禁止被其它事務select

c)         保證一個事務不會讀到其它事務已經修改但末提交的資料

d)         為SQL Server的預設隔離等級

3.       授權讀取快照

a)         不允許髒讀,也不允許丟失更新

b)         事務中已經修改的行,在沒提交事務之前, 允許被其它事務select,訪問的是該行的曆史版本(可通過READ_COMMITED_SNAPSHOT設定)。

c)         保證一個事務不會讀到其它事務已經修改但末提交的資料

4.       可重複讀取

a)         不允許髒讀,也不允許丟失更新,也不允許不可重複讀取

b)         事務中已經修改的行,在沒提交事務之前,禁止被其它事務select

c)         事務中已經讀取的行,在沒提交事務之前,也禁止其它事務的修改,允許其它事務讀取

d)         所有共用鎖定也必須保持到事務結束。

5.       序列化

a)         最嚴格的事務隔離,禁止相關事務的並發,相關事務只能一個接一個地執行。

b)         所有共用鎖定也必須保持到事務結束。

c)         不僅需要鎖定已經讀資料,還要使用‘關鍵範圍鎖定’鎖定潛在的資料,防止其它事務insert新的資料。

並發控制項模型

1.         悲觀

a)         在悲觀模型中,寫者總是阻塞讀者和寫者,而讀者也會阻塞寫者                  

2.         樂觀

a)         在樂觀模型中,唯一可能發生阻塞的是寫者阻塞寫者。

b)         上面5種隔離等級中,只有授權讀取快照屬於樂觀模型

各種鎖

1.         共用鎖定

a)         讀取資料時,會在一行,一頁,或者整個表上加上共用鎖定

b)         共用鎖定不會妨礙其它事務的讀取操作,但會使其它事務的修改操作陷入等待

2.         獨佔鎖定

a)         插入,更新,刪除操作時,會加獨佔鎖定

b)         排它鎖會持續鎖定,直到該事務結束

3.         更新鎖定

a)         當執行一個修改操作時,需要先找著等待修改的記錄的位置,此時會加上更新鎖定,來保護資料,當找著正確的位置時,更新鎖定會升級為獨佔鎖定。

b)         與共用鎖定相容

4.         意圖鎖定

a)         當執行一行資料修改時,該行會加獨佔鎖定,則該行鎖在的頁,或者表會加意向獨佔鎖定,防止另外的事務在其父容器上,如頁級或者表級擷取獨佔鎖定。

鎖的觀察

1.         sys.dm_tran_locks

a)         該視圖用來取代sp_lock預存程序,來觀察系統中的鎖狀態

b)         select object_name(object id)可查看是哪張表

2.         死結

a)         迴圈死結

                                       i.              兩個事務互相持有對方想要的鎖,就會產生死結。

b)         轉換死結

                                       i.              兩個事務均持有一個頁上的共用鎖定,又想將共用鎖定轉換為獨佔鎖定,由於;雙方共用鎖定的存在,所以無法完成,而產生死結。

c)         死結時的優先順序

                                       i.              可設定 SET DEADLOCK_PRIORITY來設定優先權,當死結發生時,低優先順序的事務將會作為犧牲者

                                     ii.              當優先順序一致時,復原開銷較低的會話會作為犧牲者。

 

附一個經典的死結:

    SqlConnection conn = new SqlConnection(connectionString);
conn.Open();
SqlTransaction tran = conn.BeginTransaction();
string sql1 = "Update Lock1 SET C1=C1+1";
string sql2 = "SELECT * FROM Lock1";
ExecuteNonQuery(tran, sql1); 

ExecuteNonQuery(null, sql2); 

重現鎖:

Query1: 

Begin Tran
  insert [User] values(1,'asdf')
  WaitFor Delay '00:00:10';

Rollback Tran; 

Query2:

  select * from [User] 

 解決方案:

       a). 把SELECT放在Update語句前:SELECT不在事務中,且執行完畢會釋放S鎖;
       b). 把SELECT也放加入到事務中:ExecuteNonQuery(tran, sql2);

       c). SELECT加With(NOLock)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.