首先要说明的是,在项目中,我们依赖于Linq2SQL做级联更新,级联更新是我们在业务层自己控制。
LINQ2SQL的Optimistic Concurrent(乐观并发)机制一,没有使用Timestamp(version列)
先看一段代码
private static void OptimisticConcurrentInColumn()
{
Product prod;
using (NutShellDataContext db = new NutShellDataContext())
{
db.Log = Console.Out;
var query = from p in db.Products
where p.ID == 1
select p;
prod = query.First() as Product;
prod.Description = "Widget";
prod.Discontinued = true;
var queryCust = from c in db.Customers
where c.ID == 1
select c;
db.SubmitChanges();
Console.WriteLine("Update product Successfully");
}
Console.ReadLine();
}
在Product表中,没有version number的字段,也就是没有Timestamp. 当默认通过vs.net中的工具生成Product类之后,看看linq2sql是如何处理并发的。
UPDATE [dbo].[Product]
SET [Description] = @p3
WHERE ([ID] = @p0) AND ([Description] = @p1) AND ([Discontinued] = 1) AND ([LastSale] = @p2)
-- @p0: Input Int (Size = 0; Prec = 0; Scale = 0) [1]
-- @p1: Input VarChar (Size = 6; Prec = 0; Scale = 0) [Widget]
-- @p2: Input DateTime (Size = 0; Prec = 0; Scale = 0) [2007-1-1 0:00:00]
-- @p3: Input VarChar (Size = 7; Prec = 0; Scale = 0) [Widgets]
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 3.5.30729.1
生成的SQL比较有意思,所有列都在where条件中,这个就是LINQ2SQL在没有timestamp时用来做乐观竞争的机制。当一条记录如果在当前用户修改之前,别人已经修改了,LINQ2SQL会阻止当前用户的修改。
at System.Data.Linq.ChangeProcessor.SubmitChanges(ConflictMode failureMode) Exception : S