在Linq to Sql中管理并發更新時的沖突(2):引發更新沖突
摘要:我們將繼續來查看Linq to Sql在管理并發更新時是如何發現沖突問題的。
[1] 在Linq to Sql中管理并發更新時的沖突(2):引發更新沖突[2] 在Linq to Sql中管理并發更新時的沖突(2):引發更新沖突
在上一講中,我們提到了一些諸如“樂觀并發控制”、“悲觀并發控制”的概念,以及察看Linq to Sql自動生成sql語句的方法。從這篇文章起我們將繼續來查看Linq to Sql在管理并發更新時是如何發現沖突問題的。
要使用Linq to Sql,我們自然需要一個數據庫環境。為了說明問題,我們這里使用一個非常簡單的數據表。
我們這里創建了一個Video表,只有3個字段,沒有約束,沒有外鍵——我們只要能夠說明問題就可以了,不是嗎?
- VideoID:主鍵,int,自增長
- Introduction:nvarchar(max),not null
- SiteID:int,not null
上面的圖片是使用Visual Studio 2008中提供的Object Relational Designer根據 數據表的Schema自動生成的。您在使用時也可以通過VS 2008提供的命令行工具 “SqlMetal.exe”來自動生成Object Model代碼。這都不是這次的重點。
目前,Video表中有這么一條記錄:
VideoID | Introduction | SiteID |
1 | Introduction 1 | 1 |
現在就開始我們的嘗試吧:
LinqToSqlDemoDataContext dataContext=new LinqToSqlDemoDataContext(); dataContext.Log = Console.Out; Video video = dataContext.Videos.Single(v => v.VideoID == 1); video.Introduction = "1235"; dataContext.SubmitChanges(); Console.ReadLine();
首先,我們獲取了VideoID為1的那條記錄,并構造成一個Video對象。接著我們修改了這個Video對象的Introduction屬性,最后調用了DataContext的SubmitChange方法將修改提交至數據庫。運行以上代碼之后,我們捕獲了輸出:
SELECT [t0].[VideoID], [t0].[Introduction], [t0].[SiteID] FROM [dbo].[Video] AS [t0] WHERE [t0].[VideoID] = @p0 -- @p0: Input Int (Size = 0; Prec = 0; Scale = 0) [1] -- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.21004.1 UPDATE [dbo].[Video] SET [Introduction] = @p3 WHERE ([VideoID] = @p0) AND ([Introduction] = @p1) AND ([SiteID] = @p2) -- @p0: Input Int (Size = 0; Prec = 0; Scale = 0) [1] -- @p1: Input NVarChar (Size = 14; Prec = 0; Scale = 0) [Introduction 1] -- @p2: Input Int (Size = 0; Prec = 0; Scale = 0) [2] -- @p3: Input NVarChar (Size = 16; Prec = 0; Scale = 0) [New Introduction] -- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.21004.1
獲取VideoID為1的記錄的Sql語句不必多說,關鍵在于那條用于更新的語句。根據它的WHERE Condition以及傳入的參數,我們不難發現它在更新時作了什么樣的判斷:除了傳入了主鍵——這是為了標識更新的那條記錄——它還將記錄原有的值傳入了Sql語句中。也就是說,只有當“更新”時,那條記錄的狀態和“獲取”時完全相同,更新才會成功。
這就是“樂觀并發控制”——直到更新時才判斷是否出現了并發問題。
嚴格說來,這只是“樂觀并發控制”的一部分,“樂觀并發控制” 還包括在并發問題出現之后“處理問題”的過程。
[第1頁][第2頁]
全站熱搜