C# nolock/TransactionScope与快照隔离

C# nolock/TransactionScope与快照隔离,c#,linq,sql-server-2008,C#,Linq,Sql Server 2008,是否应该使用快照隔离而不是nolock/TransactionScope?快照似乎是一个应用于整个数据库的db设置?这是对的吗?这是否意味着我不需要专门为它编写代码 如果我更新相关表,然后提交更改(),linq是否总是以相同的顺序更新表 谢谢首先,NoLock(和ReadUncommitted)是非常危险的。 想想看,您使用事务主要是因为您希望数据保持一致。通过使用NoLock,您可以对数据进行脏读。 比方说,在应用程序中,很有可能读取半更新或半插入的数据。您的应用程序(或用户)将根据不一致的数

是否应该使用快照隔离而不是nolock/TransactionScope?快照似乎是一个应用于整个数据库的db设置?这是对的吗?这是否意味着我不需要专门为它编写代码

如果我更新相关表,然后提交更改(),linq是否总是以相同的顺序更新表

谢谢

首先,NoLock(和ReadUncommitted)是非常危险的。 想想看,您使用事务主要是因为您希望数据保持一致。通过使用NoLock,您可以对数据进行脏读。 比方说,在应用程序中,很有可能读取半更新或半插入的数据。您的应用程序(或用户)将根据不一致的数据做出决策

如果你进入业务领域,简单地问你的应用程序所使用的数据是否可能不一致,我相信答案绝对是否定的。所以不要走这条路,我们已经走到了那里,结果是一无所获

现在谈谈订单。 据我所知,理论上不能保证它是否总是相同的顺序,但实际上可能是(因为orm通常只有一个算法来枚举实体和发现更改)。 但它并没有真正的帮助,因为即使它以相同的顺序枚举实体(以便找到需要保存的内容),实体类型的数量也可能不同。比如说,在一个场景中是A和D,在另一个场景中是A,B,D,在另一个场景中是A,C,D。现在它可能取决于这些实体之间的关系。比如说,C依赖于D,所以实际的顺序实际上是A,D,C,而不是A,C,D(即使在这里也没有规定它不会是D,C,A)。 因此,在这个订单上转载不是一个选项。要确保顺序,唯一可以做的事情是在每一个令人讨厌的步骤之后调用.SaveChanges()

是的,您可以使用快照隔离级别(有两个,基本上是任意一个,请尝试快照读取提交)。它将显著减少系统中的死锁数量,但这种方法有其自身的缺点

为了或多或少正确地解决这个问题,我建议您在系统中明确定义事务边界。系统的哪个部分“拥有”哪些数据?哪些数据必须与其他数据一致更改?然后,您可以说“仅允许这些交易”和“仅允许我的系统的此特定部分接触此特定数据”

这很难,尤其是在一开始,当你有一个读写混乱的大数据库时,到处都是。但这将导致系统更加稳定、可控和可维护


顺便说一句,Udi Dahan有一篇关于此的有趣博文:

BTW,快照隔离是服务器范围内的设置,而NOLOCK/TransactionScope更易于控制。+1用于阻止NOLOCK,也用于提及我的英雄之一Udi Dahan。