|
本文介紹了處理.NET中鎖的6種方法,首先我們討論一下并發(fā)性問題,然后討論處理樂觀鎖的3種方法,樂觀鎖不能從根源上解決并發(fā)問題,因此后面我們介紹了悲觀鎖,最后介紹隔離級別如何幫助我們實現(xiàn)悲觀鎖,每個隔離級別都列舉了示例進行說明,使得概念更加清晰。
我們?yōu)槭裁葱枰i?
在多用戶環(huán)境中,在同一時間可能會有多個用戶更新相同的記錄,這就會產(chǎn)生沖突,這個就是著名的并發(fā)性問題。
圖 1 并行性問題漫畫
如何解決并發(fā)性問題?
借助正確的鎖定策略可以解決并發(fā)性問題,資源被鎖定后,其它進程想要訪問它就會被阻止。
并發(fā)會造成什么樣的沖突?
并發(fā)主要會導(dǎo)致四種常見的問題,詳細情況請看下表。
問題 | 簡要描述 | 解釋 |
臟讀取 | 當一個事務(wù)讀取其它完成一半事務(wù)的記錄時,就會發(fā)生臟讀取 |
|
不可重復(fù)讀取 | 在每次讀數(shù)據(jù)時,如果你獲得的值都不一樣,那表明你遇到了不可重復(fù)讀取問題 |
|
虛幻行 | 如果update和delete SQL語句未對數(shù)據(jù)造成影響,很可能遇到了虛幻行問題 |
|
更新丟失 | 一個事務(wù)的更新覆蓋了其它事務(wù)的更新結(jié)果,就是所謂的更新丟失 |
|
如何解決上述沖突?
答案是使用樂觀鎖或悲觀鎖,下面將進一步進行闡述。
圖 2 樂觀鎖和悲觀鎖
什么是樂觀鎖?
顧名思義,樂觀鎖假設(shè)多個事務(wù)相互不會影響對方,換句話說就是,在樂觀鎖模式下,沒有鎖操作會得到執(zhí)行,事務(wù)只是驗證是否有其它事務(wù)修改數(shù)據(jù),如果有則進行事務(wù)回滾,否則就提交。
圖 3 樂觀鎖
樂觀鎖是如何工作的?
實現(xiàn)樂觀鎖的方法有多種,但基本原則都一樣,總是少不了下面五個步驟:
•記錄當前的時間戳
•開始修改值
•在更新前,檢查是否有其他人更新了值(通過檢查新舊時間戳實現(xiàn))
• 如果不相等就回滾,否則就提交
圖 4 樂觀鎖的工作原理
實現(xiàn)樂觀鎖的解決方案
在.NET中,實現(xiàn)樂觀鎖的方法主要有三種:
•數(shù)據(jù)集(Dataset):數(shù)據(jù)集是實現(xiàn)樂觀鎖的默認方法,在更新前它會檢查新舊值。
• 時間戳數(shù)據(jù)類型(timestamp):在你的表中創(chuàng)建一個timestamp數(shù)據(jù)類型,在更新時,檢查舊時間戳是否等于新時間戳。
•直接檢查新舊值:在更新時檢查舊值和新值是否相等,如果不相等就回滾,否則就提交。
解決方案1:數(shù)據(jù)集
正如前面所說的,數(shù)據(jù)集是處理樂觀鎖的默認方法,下面是一個簡單的快照,在Adapter的update函數(shù)上有一個調(diào)試點,當我移除斷點運行update函數(shù)時,它拋出如下圖所示的并行異常錯誤。
圖 5 Update函數(shù)執(zhí)行時拋出的異常錯誤
如果你運行后端分析器,你將會看到更新語句檢查當前值和舊值是否相等:
exec sp_executesql N'UPDATE [tbl_items] SET [AuthorName] = @p1
WHERE (([Id] = @p2) AND ((@p3 = 1 AND [ItemName] IS NULL)
OR ([ItemName] = @p4)) AND ((@p5 = 1 AND [Type] IS NULL)
OR ([Type] = @p6)) AND ((@p7 = 1 AND [AuthorName] IS NULL)
OR ([AuthorName] = @p8)) AND ((@p9 = 1 AND [Vendor] IS NULL)
OR ([Vendor] = @p10)))',N'@p1 nvarchar(11),@p2 int,@p3
int,@p4 nvarchar(4),@p5 int,@p6 int,@p7
int,@p8 nvarchar(18),@p9 int,@p10 nvarchar(2)',
@p1=N'this is new',@p2=2,@p3=0,@p4=N'1001',@p5=0,@p6=3,@p7=0,
@p8=N'This is Old
Author',@p9=0,@p10=N'kk'
NET技術(shù):.NET中鎖6大處理方法 悲觀樂觀自己掌握,轉(zhuǎn)載需保留來源!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。