• 软件测试技术
  • 软件测试博客
  • 软件测试视频
  • 开源软件测试技术
  • 软件测试论坛
  • 软件测试沙龙
  • 软件测试资料下载
  • 软件测试杂志
  • 软件测试人才招聘
    暂时没有公告

字号: | 推荐给好友 上一篇 | 下一篇

在Linq to Sql中使用记录的时间戳进行检测管理并发更新时的冲突

发布: 2008-5-07 13:52 | 作者: 网络转载 | 来源: 本站原创 | 查看: 222次 | 进入软件测试论坛讨论

领测软件测试网
try { LinqToSqlDemoDataContext dataContext = new LinqToSqlDemoDataContext(); Order order1 = dataContext.Orders.Single(o => o.OrderID == 1); Order order2 = dataContext.Orders.Single(o => o.OrderID == 2); Order order3 = dataContext.Orders.Single(o => o.OrderID == 3); Console.WriteLine('Order 1: ' + order1.Introduction); Console.WriteLine('Order 2: ' + order2.Introduction); Console.WriteLine('Order 3: ' + order3.Introduction); Console.WriteLine(); order1.Introduction = 'Order 1 modified.'; order2.Introduction = 'Order 2 modified.'; order3.Introduction = 'Order 3 modified.'; dataContext.Log = Console.Out; // 在下面的语句上设置一个断点 dataContext.SubmitChanges(); } catch (ChangeConflictException e) { Console.WriteLine('---------- ' + e.Message + ' ----------'); } LinqToSqlDemoDataContext db = new LinqToSqlDemoDataContext(); Order o1 = db.Orders.Single(o => o.OrderID == 1); Order o2 = db.Orders.Single(o => o.OrderID == 2); Order o3 = db.Orders.Single(o => o.OrderID == 3); Console.WriteLine('Order 1: ' + o1.Introduction); Console.WriteLine('Order 2: ' + o2.Introduction); Console.WriteLine('Order 3: ' + o3.Introduction); Console.ReadLine();
  假设我们的数据表里有以下三条记录:
OrderID Name Introduction record_version 1 Order 1 This is order 1Binary data> 2 Order 2 This is order 2Binary data> 3 Order 3 This is order 3Binary data>
  当程序进入到SubmitChanges语句的断点时,我们去数据库中运行以下代码,以修改OrderID为2的记录。
UPDATE Order SET OrderID = "New Order 2" WHERE OrderID = 2
  继续运行程序,最终控制台中会打印出以下信息:
Order 1: This is order 1 Order 2: This is order 2 Order 3: This is order 3 UPDATE [dbo].[Order] SET [Introduction] = @p2 WHERE ([OrderID] = @p0) AND ([record_version] = @p1) SELECT [t1].[record_version] FROM [dbo].[Order] AS [t1] WHERE ((@@ROWCOUNT) > 0) AND ([t1].[OrderID] = @p3) -- @p0: Input Int (Size = 0; Prec = 0; Scale = 0) [1] -- @p1: Input Timestamp (Size = 8; Prec = 0; Scale = 0) [SqlBinary(8)] -- @p2: Input NVarChar (Size = 26; Prec = 0; Scale = 0) [Order 1 modified.] -- @p3: Input Int (Size = 0; Prec = 0; Scale = 0) [1] -- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.21022.8 UPDATE [dbo].[Order] SET [Introduction] = @p2 WHERE ([OrderID] = @p0) AND ([record_version] = @p1) SELECT [t1].[record_version] FROM [dbo].[Order] AS [t1] WHERE ((@@ROWCOUNT) > 0) AND ([t1].[OrderID] = @p3) -- @p0: Input Int (Size = 0; Prec = 0; Scale = 0) [2] -- @p1: Input Timestamp (Size = 8; Prec = 0; Scale = 0) [SqlBinary(8)] -- @p2: Input NVarChar (Size = 26; Prec = 0; Scale = 0) [Order 2 modified.] -- @p3: Input Int (Size = 0; Prec = 0; Scale = 0) [2] -- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.21022.8 ---------- 1 of 2 updates failed. ---------- Order 1: This is order 1 Order 2: This is order 2 Order 3: This is order 3
  首先我们分别打印出三个Video对象的Introduction并将它们修改为新的值。在SubmitChanges方法调用之前,数据库中ID为2的记录已经被修改过了,因此在第一组UPDATE+SELECT调用成功之后——请注意,这是一次调用,Linq to Sql每次更新一条记录——在更新第二条记录之后发现了并发冲突。于是抛出异常(请注意异常的Message表示“两次更新其中有一次失败了”),第三条记录也不会再更新了。在冲突发生之后,ID为2和纪录自然没有被修改(WHERE条件不成立),但是第一条记录呢?从try...catch块之后的操作中看,ID为1的记录也没有被更新。

  也就是说,第一次更新被回滚了。这自然是事务的作用。在调用(默认的) SubmitChanges方法时,Linq to Sql会把所有的更新放在同一个事务中,因此它们“共同进退”。但是由于业务需求不同,有时候我们不希望某条记录的冲突导致了所有更新失败。自然, Linq to Sql也提供了这个方面的控制。在下一篇文章中,我们就来看一下Linq to Sql中与乐观并发控制有关的事务问题,以及出现并发冲突之后的解决方式。拼吾爱

延伸阅读

文章来源于领测软件测试网 https://www.ltesting.net/

TAG: LINQ Linq sql SQL Sql 管理 检测 记录


关于领测软件测试网 | 领测软件测试网合作伙伴 | 广告服务 | 投稿指南 | 联系我们 | 网站地图 | 友情链接
版权所有(C) 2003-2010 TestAge(领测软件测试网)|领测国际科技(北京)有限公司|软件测试工程师培训网 All Rights Reserved
北京市海淀区中关村南大街9号北京理工科技大厦1402室 京ICP备10010545号-5
技术支持和业务联系:info@testage.com.cn 电话:010-51297073

软件测试 | 领测国际ISTQBISTQB官网TMMiTMMi认证国际软件测试工程师认证领测软件测试网