while (AllowRun) { try { using (DbContext context = GetNewDbContext()) { while (AllowRun && context.GetConnection().State == ConnectionState.Open) { TEntity entity = null; try { while (pendingLogs.Count > 0) { lock (pendingLogs) { entity = null; if (pendingLogs.Count > 0) { entity = pendingLogs[0]; pendingLogs.RemoveAt(0); } } if (entity != null) { context.Entities.Add(entity); } } context.SaveChanges(); } catch (Exception e) { // (1) // Log exception and continue execution } } } } catch (Exception e) { // Log context initialization failure and continue execution } }
(这主要是实际的代码,我省略了几个不相关的部分,试图将弹出的对象保留在内存中,直到我们能够在(1)块捕获异常时再次将内容保存到DB)
所以,基本上,有一个无限循环,试图从一些列表中读取项目并将它们保存到Db.如果我们检测到与DB的连接由于某种原因失败,它只是尝试重新打开并继续.问题是有时候(我到目前为止还没弄清楚如何重现它),上面的代码在调用context.SaveChanges()时开始产生以下异常(在(1)块中捕获):
System.Data.EntityException: An error occurred while starting a transaction on the provider connection. See the inner exception for details. ---> system.invalidOperationException: The requested operation cannot be completed because the connection has been broken.
记录错误,但是当执行返回到context.GetConnection().State == ConnectionState.Open check时,它的计算结果为true.因此,当上下文报告其数据库连接已打开时,我们处于一种状态,但我们无法针对该上下文运行查询.重新启动服务可以解决问题(以及在调试器中弄乱AllowRun变量以强制重新创建上下文).所以问题是因为我不能信任上下文的连接状态,我如何验证我可以对DB运行查询?
还有,有一种干净的方法可以确定连接是否处于“健康”状态?我的意思是,EntityException本身并不表示我应该重置连接,只有当它的InnerException是带有一些特定Message的InvalidOperationException时,是的,是时候重置它了.但是,现在我想在ConnectionState指示一切正常时会有其他情况,但我无法查询数据库.我可以主动抓住这些,而不是等到它开始咬我?
解决方法
如果此循环花费的时间超过连接超时,则在savechanges执行时连接关闭.
while (pendingLogs.Count > 0) { lock (pendingLogs) { entity = null; if (pendingLogs.Count > 0) { entity = pendingLogs[0]; pendingLogs.RemoveAt(0); } } if (entity != null) { context.Entities.Add(entity); } } context.SaveChanges();
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。