Entity Framework中的并发异常

24
在Entity Framework (CF, C#)中调用 SaveChanges / SaveChangesAsync 时,如果出现变更冲突(例如值自上次读取后已更新),那么我应该捕获这两个异常之一:DbUpdateConcurrencyExceptionOptimisticConcurrencyException
它们之间有什么区别?

根据你得到的答案,你有没有考虑过花一秒钟查阅文档中的异常并阅读这些描述呢?你基本上是在要求引用文档。 - TomTom
9
当然,我已经阅读了文档,但是由于它们看起来非常相似,对我来说并没有太多意义。“在乐观并发异常可能发生时使用它”。因此,我在我的问题中提供了一个情境,并在那个背景下进行了询问! - Flair
我同意Flair文档关于DbUpdateException、DbUpdateConcurrencyException、OptimisticConcurrencyException以及如何捕获并处理并发异常的内容,但这些文档并没有明确说明应该捕获哪些异常。 - Ghini Antonio
2个回答

21

DbUpdateConcurrencyException 是由 DbContext 引发的特定异常,因此这是需要捕获的异常。此异常可能由基础的 OptimisticConcurrencyException 引起,但如果是这样,则该异常被包装为内部异常。

并非所有更新异常都是由并发引起的,因此在捕获 DbUpdateConcurrencyException 之后,还必须捕获 DbUpdateException (因为前者是 DbUpdateException 的子类型)。

另请参见Entity framework 5.0 如何处理乐观并发异常?.


谢谢您的回答,这似乎是最有可能的情况。我会尝试捕获两个异常并看看会发生什么。也感谢您提供的链接。 - Flair
1
是的,当然,并不是所有的异常都是由并发引起的,但我只关心那些类型的异常(正如我在问题中提到的:如果数据状态在你读取数据和调用SaveChanges之间在数据库中发生了变化)。我想对于我的目的,DbUpdateConcurrency异常应该就足够了,对吗?更具体地说,我该如何在Entity Framework中模拟Linq-2-SQL中的ChangeConflictException - Flair
1
捕获 DbUpdateConcurrencyException 是处理与 EF 中乐观并发相关的所有内容所需的,这些内容由时间戳/行版本列或 ConcurrencyMode.Fixed 列配置(如果您在 DbContext API 中)。另请参见 http://msdn.microsoft.com/en-us/data/jj592904.aspx。我只提到了 DbUpdateException,因为捕获的顺序很重要。 - Gert Arnold

2
您将会收到一个 OptimisticConcurrencyException。请参考这里
现在让我们来看看它们之间的区别:
- OptimisticConcurrencyException:当出现乐观并发冲突时抛出(例如,假设有多个人正在更改相同的结果,并且这将导致不同步的问题)。 - DbUpdateConcurrencyException:在DbContext期望SaveChanges对实体进行数据库更新但实际上数据库没有受到影响的情况下抛出异常。这表明数据库已经被并发更新,而预期匹配的并发标记实际上未能匹配。由于安全性和对状态条目的访问,在序列化过程中不会对此异常引用的状态条目进行序列化,对于序列化后的状态条目的访问将返回null。

链接已失效,而且对于 EF 来说建议是不正确的。 - timmi4sa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接