nolock / TransactionScope与快照隔离

时间:2012-02-07 05:01:20

标签: c# linq sql-server-2008

是否应该使用快照隔离而不是nolock / TransactionScope?快照看起来像一个db设置,适用于整个数据库?这是正确的,这是否意味着我不需要专门为它编码?

如果我更新相关表然后更新SubmitChanges(),linq是否会始终以相同的顺序更新表?

由于

1 个答案:

答案 0 :(得分:2)

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

如果您去公司并且只是询问您的申请所处的数据是否不一致,我相信答案将是严格的。所以,不要走这条路,我们一直在那里,它最终无处可去。

现在关于订单。 据我所知,理论上不保证它是否总是相同的顺序,但实际上它可能是(因为ORM通常只有一个算法来枚举实体并发现变化)。 但它并没有真正帮助,因为即使它按照相同的顺序枚举实体(为了找到需要保存的内容),实体类型的数量可以是不同的。比如,在一个场景中是A和D,在另一个场景中是A,B,D,在另一个场景中是A,C,D。现在它可能取决于这些实体之间的关系。比方说,C取决于D,所以实际的顺序实际上是A,D,C,而不是A,C,D(甚至在这里没有指明它不会是D,C,A)。 所以继续这个订单不是一个选择。你唯一能做的就是确保顺序是在每个令人讨厌的步骤之后调用.SaveChanges()。

是的,您可以使用Snapshot隔离级别(有两个,基本上任何一个,尝试Snapshot Read Committed)。它将大大减少系统中的死锁数量,但这种方法有其自身的缺点。

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

这很难,特别是在一开始你有一个混乱的大型数据库,来自世界各地的一切。但它导致更稳定,可控和可维护的系统。

BTW,Udi Dahan有一篇有趣的博客文章:Inconsistent data, poor performance, or SOA – pick one