書讀百遍,不如 敲一遍代碼...
先解釋一下名詞
共享鎖(S):一般是Select 查詢是自帶共享鎖圈盔;共享鎖允許多個用戶同時查詢和修改(默認是這樣,除非單獨設置共享鎖的生命周期近她,以下會說到);
排它鎖(X):一般是Insert湖蜕,Update,Delete時會自動加排它鎖叨吮;
我們先看一個正常的例子:
一辆布,
多個事務查詢框模擬多個用戶:
begin tran
-- S鎖
select * from users where id= 1
--等待10秒
WaitFor DELAY '00:00:05'
commit;
begin tran
update users set Name= 'ttttt3' where id = 1
commit;
此時:第二個事務查詢框不受第一個查詢框的影響,可以直接出數據挤安;證明Select的共享鎖在查詢后直接就默認釋放掉了谚殊;
二,
begin tran
-- S鎖
select * from users with(holdlock) where id= 1
--等待10秒
WaitFor DELAY '00:00:05'
commit;
begin tran
update users set Name= 'ttttt3' where id = 1
commit;
此時:第二個事務的更新操作受第一個事務的影響蛤铜,需要等待5秒也就是第一個事務Commit的時候,才能執(zhí)行丛肢;with(holdlock) 就是人為的提高了事務一Select共享鎖的生命周期围肥;
三,
begin tran
update users set Name= 'tt' where id = 1
WaitFor DELAY '00:00:05'
commit;
begin tran
-- S鎖
select * from users where id= 1
commit;
此時:第二個事務的更新或者查詢操作受第一個事務的影響蜂怎,需要等待5秒也就是第一個事務Commit的時候穆刻,才能執(zhí)行;第一個事務的update操作添加了排它鎖杠步,只有等commit提交事務的時候才會釋放氢伟;
四榜轿,
begin tran
update users set Name= 'tt222' where id = 1
WaitFor DELAY '00:00:05'
commit;
--rollback
begin tran
-- S鎖
select * from users with(nolock) where id= 1
commit;
此時:第二個事務者查詢操作不受第一個事務的影響,可以直接出結果朵锣;但是第二個事物使用了with(nolock) 就是忽略鎖的意思谬盐; 在第一個事務失敗rollback的情況下可能會出現臟讀的情況(第二個事物實際讀取的是第一個事務的更新后的數據);
五诚些,死鎖
begin tran
update users set Name= 'tt'
WaitFor DELAY '00:00:05'
-- S鎖
select * from uu with(holdlock)
commit;
begin tran
update uu set Name= 'ttttt3'
--WaitFor DELAY '00:00:50'
select * from users with(holdlock)
commit;
此時:
兩個事務之間出現死鎖飞傀; 事務一對users添加排它鎖,并同時等待5秒鐘诬烹; 事務二對uu 添加排它鎖砸烦,并以(holdlock)方式 訪問users表,但此時users排它鎖并沒有釋放绞吁,所以無法添加共享鎖幢痘,所以一直等待事務一釋放排它鎖;
此時事務一訪問uu 家破,同樣的uu排它鎖并未釋放颜说,由此導致兩個事務之間相互等待造成死鎖;
死鎖的造成方式還有很多種员舵,總結就是對A中的A1添加了排它鎖脑沿,在B中B1添加了排它鎖,同時在A中訪問B1,在B中訪問A1马僻,由此相互等待造成死鎖庄拇;
最后附上鎖類型:
HOLDLOCK: 在該表上保持共享鎖,直到整個事務結束韭邓,而不是在語句執(zhí)行完立即釋放所添加的鎖措近。
NOLOCK:不添加共享鎖和排它鎖女淑,當這個選項生效后瞭郑,可能讀到未提交讀的數據或“臟數據”,這個選項僅僅應用于SELECT語句鸭你∏牛
PAGLOCK:指定添加頁鎖(否則通常可能添加表鎖)袱巨「笞唬
READCOMMITTED用與運行在提交讀隔離級別的事務相同的鎖語義執(zhí)行掃描。默認情況下愉老,SQL Server 2000 在此隔離級別上操作场绿。
READPAST: 跳過已經加鎖的數據行,這個選項將使事務讀取數據時跳過那些已經被其他事務鎖定的數據行嫉入,而不是阻塞直到其他事務釋放鎖焰盗,READPAST僅僅應用于READ COMMITTED隔離性級別下事務操作中的SELECT語句操作璧尸。
READUNCOMMITTED:等同于NOLOCK熬拒∫猓
REPEATABLEREAD:設置事務為可重復讀隔離性級別∶蜗妫
ROWLOCK:使用行級鎖瞎颗,而不使用粒度更粗的頁級鎖和表級鎖“埔椋
SERIALIZABLE:用與運行在可串行讀隔離級別的事務相同的鎖語義執(zhí)行掃描哼拔。等同于 HOLDLOCK“曷
1TABLOCK:指定使用表級鎖倦逐,而不是使用行級或頁面級的鎖,SQL Server在該語句執(zhí)行完后釋放這個鎖宫补,而如果同時指定了HOLDLOCK檬姥,該鎖一直保持到這個事務結束》叟拢
TABLOCKX:指定在表上使用排它鎖健民,這個鎖可以阻止其他事務讀或更新這個表的數據,直到這個語句或整個事務結束。
UPDLOCK :指定在讀表中數據時設置更新 鎖(update lock)而不是設置共享鎖窘拯,該鎖一直保持到這個語句或整個事務結束可款,使用UPDLOCK的作用是允許用戶先讀取數據(而且不阻塞其他用戶讀數據)炊昆,并且保證在后來再更新數據時,這一段時間內這些數據沒有被其他用戶修改。