实体框架 - 更新异常
我刚刚注意到,当使用实体框架更新数据时发生 SqlException
时,对 SaveChanges
的所有后续调用都将失败,因为导致异常的实体仍在“队列”中被拯救。
这让我们在实时系统上感到很不舒服,因为许多用户由于更新失败并出现错误“字符串或二进制数据将被截断
”而无法保存数据。我们只得求助于回收应用程序池。
如何删除/重置有问题的对象并让其他更新继续进行?
编辑:更好的是,处理插入/更新期间发生的 Sql 异常的最佳方法是什么?
I just noticed that when a SqlException
occurs while updating data using Entity Framework, all subsequent calls to SaveChanges
will fail because the Entity that caused the exception is still in the "queue" to be saved.
This just stung us on a live system as many users were not able save their data due to some failed update with error 'string or binary data would be truncated
'. We just had to resort to recycling the application pool.
How can I remove/reset the offending object and let other updates go through?
EDIT: Better yet, what is the best way of handling Sql Exeptions that occur during insert/update?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
EF 的第一个基本规则 -
ObjectContext
是工作单元,因此您必须以这种方式处理它。如果您在用户之间共享上下文,那么您犯了很大的错误,您应该立即关闭该应用程序,并且不要让您的用户使用它,除非您进行修复。我写了答案,其中描述了上下文正在实现的两种模式 -工作单元和身份映射。如果您在并发用户之间共享上下文,则会导致每个操作的结果不确定。您不能说用户是否有新的/提交的数据,也不能说您是否保存了用户在单个事务中修改的所有内容。现在上下文在内部使用事务。每个 SaveChanges 都会保存事务中的每个修改记录(如果共享上下文,则来自所有并发用户)。单个错误和整个事务将被回滚。一旦开始为每个逻辑操作(Web 应用程序中的请求或操作)使用上下文,您就可以向用户显示数据并让他进行修改,或者您可以简单地再试一次(在处理锁定问题的情况下)。这当然不能解决不验证用户输入的问题,因为这是应用程序中必须修复的错误。如果没有验证,就无法向用户显示数据有什么问题。
First essential rule of EF -
ObjectContext
is unit of work and because of that you have to deal it with this way. If you share context among users you did so big mistake that you should immediately turn off the application and don't let your users use it unless you make a fix. I wrote the answer where I describing two patterns the context is implementing - unit of work and identity map. If you share the context among concurrent users you make the result of each operation undeterministic. You can't say if user has a fresh / commited data and you can't say if you saved everything the user was modifying in the single transaction.Now the context uses transaction internally. Each
SaveChanges
saves every modified record (from all concurrent users if you share the context) in the transaction. Single error and whole transaction is rolled back. Once you start to use context per logical operation (request or action in the case of web application) you can show user the data and let him do modification or you can simply try it again (in case of dealing with locking issues). This of course doesn't solve problems where you do not validate user input because that is the bug in application which must be fixed. If you don't have a validation you can't show the user what is wrong with data.您可以通过遵循工作单元模式和您的上下文来保护自己免受这种情况的影响。
在这种情况下,来自不同用户的每次更新都将使用自己的上下文......因此,如果其中一个出现错误,则不会影响其他用户。
看一下:
在 Entity Framework 4.0 中使用存储库和工作单元模式
工作单元还将帮助您了解如何从错误中恢复。
由于单个工作单元本质上是单个事务,因此您可以简单地回滚事务并通知用户(并允许他们修改数据并重试)。
You can protect yourself from that situation by following the Unit of Work pattern with your context.
In that situation, each update from a different user would use its own context...so if an error was present in one it wouldn't affect the others.
Take a look at:
Using Repository and Unit of Work patterns with Entity Framework 4.0
The Unit of Work will also help you understand how to recover from an error.
Since a single Unit of Work is, in essence, a single transaction you can simply roll back the transaction and notify the user (and allow them to modify their data and try again).