實(shí)例演示SQL Server中五個(gè)事務(wù)隔離的區(qū)別
網(wǎng)上里有很不錯(cuò)的介紹SQL Server事務(wù)隔離的文章,感覺很多都從概念入手介紹的,對那些初學(xué)者來說,看得見摸得著的理解才深刻,故不再重復(fù),重點(diǎn)在于實(shí)例演示上面。
首先解釋下事務(wù)隔離是干什么的,一個(gè)事務(wù)的隔離級別控制了它怎么樣影響其它事務(wù)和被其它事務(wù)所影響。
1、READ UNCOMMITTED,會導(dǎo)致臟讀(能讀取其它事務(wù)沒有提交的更改)和不可重復(fù)讀(事務(wù)讀取的數(shù)據(jù)被其它事務(wù)所修改,再次讀取時(shí)不一致)
初始化:
CREATE TABLE TranLevel (k int IDENTITY(1,1), val int) INSERT INTO TranLevel(val) values(1) INSERT INTO TranLevel(val) values(2) INSERT INTO TranLevel(val) values(3) |
首先執(zhí)行Query1,再新建查詢立即執(zhí)行Query2
Query1:
BEGIN TRAN Query1 -- 在事務(wù)中修改 UPDATE TranLevel SET val = 9 -- '等待10秒,期間事務(wù)2運(yùn)行' WAITFOR DELAY '00:00:10' -- 不提交修改,回滾事務(wù) ROLLBACK TRAN Query1 |
Query2:
-- 設(shè)置當(dāng)前會話事務(wù)隔離級別為未提交讀 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED BEGIN TRAN Query2 SELECT '事務(wù)2開始并發(fā)執(zhí)行,讀取到了事務(wù)1修改了但沒有提交的數(shù)據(jù),是臟讀' SELECT * FROM Tranlevel SELECT '事務(wù)2等待10秒,讓事務(wù)1執(zhí)行完' WAITFOR DELAY '00:00:10' SELECT '兩次讀取的結(jié)果不一致,是不可重復(fù)讀' SELECT * FROM TranLevel COMMIT TRAN Query2 |
下面就看看Query2執(zhí)行的結(jié)果是怎樣的:
結(jié)果顯而易見,如果將事務(wù)隔離級別設(shè)置為未提交讀,則會造成臟讀和不可重復(fù)讀的問題,在這幾個(gè)事務(wù)隔離級別中是限制最小的一個(gè),SQL Server分配的資源也最小。
初始化:
drop Table tranlevel CREATE TABLE TranLevel (k int IDENTITY(1,1), val int) INSERT INTO TranLevel(val) values(1) INSERT INTO TranLevel(val) values(2) INSERT INTO TranLevel(val) values(3) |
Query3:
SET TRANSACTION ISOLATION LEVEL READ COMMITTED BEGIN TRAN Query3 -- 等待10秒,再修改數(shù)據(jù) WAITFOR DELAY '00:00:10' UPDATE TranLevel SET val = 10 COMMIT TRAN Query3 |
Query 4:
SET TRANSACTION ISOLATION LEVEL READ COMMITTED BEGIN TRAN Query4 SELECT '查到的是Query3沒有提交前的數(shù)據(jù)' SELECT * FROM TranLevel SELECT '讓Query3執(zhí)行完' WAITFOR DELAY '00:00:10' SELECT '再次查詢,數(shù)據(jù)就變成Query3執(zhí)行完后的數(shù)據(jù)了' SELECT * FROM TranLevel COMMIT TRAN Query4 |
執(zhí)行Query3后,新建查詢執(zhí)行Query4。下面看看Querry4查詢得到的數(shù)據(jù)。
結(jié)果就是Query4中的事務(wù)查詢獲得了在Query3提交后的數(shù)據(jù),在同一事務(wù)中讀取的數(shù)據(jù)不一致,造成了不可重復(fù)讀。