在Linq to Sql中管理并发更新时的冲突(1) 预备知识

无论与目前的ORM框架相比有没有优势,Linq to Sql在语言和平台的级别上 为我们提供了一种新的操作对象和数据的方式,在一定程度上为我们解决了 Object != Data的问题。在实际应用中,对于数据库的操作往往有着天生的并发 性,因此在更新数据时可能会产生冲突。有些时候,如果没有合理的解决冲突问 题,轻则让用户摸不着头脑,重则让系统数据处于一种不一致的状态。Linq to Sql自然考虑到了这一点,本系列讨论的内容,就是在使用Linq to Sql时,如何 管理并发更新时产生的冲突。

本文为这个系列的第一篇,将讨论一些预 备知识,它们是进行后续研究的基础。

一些定义:

首先,我们来看一 些定义:

并发(Concurrency):两个或更多的用户尝试同时更新数据库 的同一条记录。

并发冲突(Concurrency Confilct):两个或更多的用 户尝试同时向同一条记录的一个或多个字段提交冲突的值。

并发控制( Concurrency Control):解决并发冲突的技术。

乐观并发控制 (Optimistic Concurrency Control):在提交当前事务之前,首先查看即将更 新的记录是否被别的事务所改变的一种技术。

悲观并发控制 (Pessimistic Concurrency Control):为纪录加锁以阻止其他事务访问某些 记录,以避免产生并发冲突的一种技术。

Linq to Sql的对象模型使用 乐观并发控制的方式来发现和解决冲突问题。很显然,它假设冲突发生的可能性 并不大。如果您需要使用悲观并发控制来解决冲突问题,则可以使用其他方法( 例如自定义存储过程供程序调用)。

调试方法:

Linq to Sql的相当 部分由编译器来实现,而语言中的Linq语句最终会被转化为Sql,因此如果要理 解Linq to Sql的工作,一定要将操作中所执行的Sql语句给挖掘出来。一般来说 ,要挖掘出操作中所使用的Sql语句,可以使用以下几种方法(以下将使用Sql Server 2005自带的AdventureWorks数据库来作为示例):

1、获取Query 所对应的SqlCommand对象:

在开发过程中,我们可以通过Query获得对应的 Sql Command对象。请看如下代码:

AdventureWorksDataContext db = new AdventureWorksDataContext();
var products = from p in db.Products
        where p.ProductID == 3
         select new { p.ProductID, p.Name };
foreach (var p in products)
{
  Console.WriteLine(p);
}
DbCommand cmd = db.GetCommand(products);
Console.WriteLine("--------- ---");
Console.WriteLine("Command Text: \n{0}", cmd.CommandText);
Console.WriteLine("------------");
Console.WriteLine("Command Type: \n{0}", cmd.CommandType);
Console.WriteLine("------------");
Console.WriteLine("Command Parameters:");
foreach (DbParameter p in cmd.Parameters)
{
  Console.WriteLine ("{0}: {1}", p.ParameterName, p.Value);
}
Console.ReadLine();

输出结果如下:

Command Text:
SELECT [t0].[ProductID], [t0].[Name]
FROM [Production].[Product] AS [t0]
WHERE [t0].[ProductID] = @p0
------------
Command Type:
Text
------------
Command Parameters:
@p0: 3

可以看到,无论是Sql语句或是 参数都被打印了出来。事实上,由于我们得到了完整的SqlCommand对象,我们可 以获取的信息并不止上述这些。

时间: 2024-10-27 12:34:44

在Linq to Sql中管理并发更新时的冲突(1) 预备知识的相关文章

在Linq to Sql中管理并发更新时的冲突(3):使用记录的时间戳

在<在Linq to Sql中管理并发更新时的冲突(2):引发更新冲突>一文中 ,我们描述了Linq to Sql检测在更新时是否产生了冲突的基本方法:将该记录 每个字段原来的值和更新时的值进行对比,如果稍有不同则意味着记录被修改过 ,因此产生了更新冲突.不过您是否有这样的感觉,这种方法实在累赘了一些? 如果一个表中有数十个字段,那么更新就必须完整地检测一遍(不过我会在今后 的文章中提到这方面的控制).再者,如果其中某一个字段储存了洋洋洒洒上万 字的文章,那么在验证时仅仅是将它从Web服务器发

在Linq to Sql中管理并发更新时的冲突(2) 引发更新冲突

在上一讲中,我们提到了一些诸如"乐观并发控制"."悲 观并发控制"的概念,以及察看Linq to Sql自动生成sql语句的方法.从 这篇文章起我们将继续来查看Linq to Sql在管理并发更新时是如何发现冲突问 题的. 要使用Linq to Sql,我们自然需要一个数据库环境.为了说明问 题,我们这里使用一个非常简单的数据表. 我们这里创建了一个Video表,只有3个字段,没有约束,没有外键 --我们只要能够说明问题就可以了,不是吗? VideoID:主 键,i

linq to sql中的自动缓存(对象跟踪)

这篇东西应该至少一年前就写的,不过因为个人太懒,一直没记下来,今天补上.   linq to sql中,对于同一个DataContext上下文环境,根据表主键选择记录时(当然这里所指的"记录"会自动转成"对象"),如果该记录已经被select过,默认情况下会被自动缓存下来,下次再选择时,将自动返回已缓存的对象,而不是重新从数据库里查询.   在很多情况下(特别是查询的场景),这会提高性能(因为避免了数据库重复查询),但是也时候也会带来麻烦:   比如我们取出一个对象

在LINQ to SQL中使用Translate方法以及修改查询用SQL

目前LINQ to SQL的资料不多--老赵的意思是,目前能找到的资 料都难以摆脱"官方用法"的"阴影".LINQ to SQL最 权威的资料自然是MSDN,但是MSDN中的文档说明和实例总是显得"大开大 阖",依旧有清晰的"官方"烙印--这简直是一 定的.不过从按照过往的经验,在某些时候如果不按照微软划定的道道来走,可 能就会发现别样的风景.老赵在最近的项目中使用了LINQ to SQL作为数据层的基础,在LINQ to S

Linq to SQL中的实体继承

现在的Linq To Sql只支持单表继承,不支持一实体一具体表和一实体一扩展表等方式继承.什么是单 表继承呢?所谓单表继承就是把整个继承体系存储在数据库的一个表中.由此可以知道,这个表结构包括 所有实体的属性字段,如果在该继承体系中,实体的数量较多,就会产生大量的null值的数据,这样浪费 了很多的数据存储空间.不过所有的继承体系放在一个表中,逻辑简单容易操作,数据量不大的时候效率 也高.下面看看在Linq To Sql中是怎样实现单表继承的(用Orcas白皮书中的示例来说明). 假如现在有这

[转]Linq to SQL中的实体继承

原文:http://www.cnblogs.com/blusehuang/archive/2007/07/05/807027.html    现在的Linq To Sql只支持单表继承,不支持一实体一具体表和一实体一扩展表等方式继承.什么是单表继承呢?所谓单表继承就是把整个继承体系存储在数据库的一个表中.由此可以知道,这个表结构包括所有实体的属性字段,如果在该继承体系中,实体的数量较多,就会产生大量的null值的数据,这样浪费了很多的数据存储空间.不过所有的继承体系放在一个表中,逻辑简单容易操作

LINQ TO SQL中还是用传统的连接串方式建立DbContext更好些

    首先,在LINQTOSQL中可以这样建立一个dbcontext     private TEntity GetOriginal(TEntity entity)        {            using (Entity.EEE114.LinqEEE114DataContext context = new Entity.EEE114.LinqEEE114DataContext())            {                var table = context.Ge

LINQ TO SQL中SQLMetal和Mapping文件缺陷

Mapping文件的缺陷 开发LINQ TO SQL,我个人倾向选择外部配置文件的方式进行开发,灵活,(这个也是.Net平台下的建议选择,如果你了解WCF,会更有体会). 利用SQLMeatal开发Mapping文件的时候,在修改Association节的DeleteRule属性的时候,感觉是LING TO SQL的缺陷. MSND: NET Framework 类库 AssociationAttribute..::.DeleteRule 属性 更新:2007 年 11 月 获取或设置关联的删除

如何在Linq to sql中进行left join

可以用 into 语法,配合 DefaultIfEmpty() 方法加载右侧表中的空值. 例子: var query = from r in db.Roles join sr in ( from ss in db.StaffInRoles where ss.StaffId == staffId select ss ) on r.Id equals sr.RoleId into x from y in x.DefaultIfEmpty() select new RoleInfo { RoleId