生产环境中出现未解释的SQL错误-可能与网络有关

7
我正在进行一些相当密集的数据库工作,并最终将许多记录插入到数据库中。为了最小化上下文膨胀,我每次进行100次插入,处理完上下文后重新创建上下文。
我遇到了一些奇怪的错误,我不明白这些错误。这些错误只在我们的生产服务器上发生,但在开发服务器上一切正常。如果有人能够解释可能出现的问题,我会非常感激。
System.Data.Entity.Core.EntityCommandExecutionException: 执行命令时发生错误。有关详细信息,请参阅内部异常。 System.Data.SqlClient.SqlException: 在接收服务器返回结果时发生传输级别错误(提供程序:TCP 提供程序,错误:0 - 信号量超时期已到期)。 System.ComponentModel.Win32Exception: 信号量超时期已到期。 System.Data.SqlClient.SqlException (0x80131904): 在接收服务器返回结果时发生传输级别错误(提供程序:TCP 提供程序,错误:0 - 指定的网络名称不再可用)。 System.ComponentModel.Win32Exception (0x80004005): 指定的网络名称不再可用。 System.Data.Entity.Infrastructure.CommitFailedException: 在提交数据库事务时报告了一个错误,但无法确定事务在数据库服务器上成功还是失败。请参阅内部异常和http://go.microsoft.com/fwlink/?LinkId=313468以获取更多信息。 System.Data.SqlClient.SqlException: 在接收服务器返回结果时发生传输级别错误(提供程序:TCP 提供程序,错误:0 - 指定的网络名称不再可用)。 System.ComponentModel.Win32Exception: 指定的网络名称不再可用。 System.Data.Entity.Core.EntityException: 已引发一个异常,可能是由于短暂故障引起。如果您正在连接到 SQL Azure 数据库,请考虑使用 SqlAzureExecutionStrategy。 System.Data.Entity.Core.EntityCommandExecutionException: 执行命令时发生错误。有关详细信息,请参阅内部异常。 System.Data.SqlClient.SqlException: 在向服务器发送请求时发生传输级别错误(提供程序:TCP 提供程序,错误:0 - 远程主机强制关闭了现有连接)。 System.ComponentModel.Win32Exception: 远程主机强制关闭了现有连接。
这些错误在过程中出现的时间完全是随机的(我有一个计数器告诉我在哪里)。查找这些错误时,似乎它们是网络错误。我无法访问我的数据库服务器日志,所以我无法在那里查看。我的Web服务器日志没有揭示发生了什么。任何帮助都将是fantastic。
编辑:
我没有运行Azure。
我也遇到了很多主键冲突错误:
System.Data.Entity.Infrastructure.DbUpdateException:更新条目时发生错误。请参见内部异常以获取详细信息。
System.Data.Entity.Core.UpdateException:更新条目时发生错误。请参见内部异常以获取详细信息。
System.Data.SqlClient.SqlException:违反'PK_dbo.MissileDataReferences'主键约束。无法在对象'dbo.MissileDataReferences'中插入重复键。重复键值为(4277,2,448388)。
1个回答

4
很烦人,不是吗?是的,在任何高访问量的网站上都会遇到这个问题。
这似乎是为什么甚至微软也在SQL Azure中引入了Azure重试策略。你希望即使是他们也能保证他们的网站与位于同一数据中心、同一网络上的数据库之间的连接。但他们不能。
你可以为Azure打开此功能(不确定你是否正在使用Azure,但我认为不是)。请参见https://learn.microsoft.com/en-us/azure/sql-database/sql-database-connectivity-issues,了解所需的连接字符串更改。 https://msdn.microsoft.com/en-us/library/dn456835(v=vs.113).aspx还介绍了Azure上的EF6。
也许这不是你想要的答案,但我认为你应该考虑使用Polly库,因为它可以让你为每个命令显式设置重试逻辑。
为什么你不想对每个调用都这样做(以节省针对每个命令编写重试代码)?好吧,过去我遇到过很多问题,我们重试插入逻辑等,然后在一会儿后再次重复(导致主键冲突),因为响应没有返回给客户端。
因此,仅对安全的“只读”调用执行此操作,并且如果必须对写入进行重试,请放置处理程序以检测重复插入,然后与服务器进行双重检查,并询问用户他们想做什么。

我已经编辑了我的原始帖子并提供了更多信息。目前我没有进行任何重试(据我所知)。除非Entity Framework内置了重试机制(我认为它没有),否则我不应该看到主键冲突(但我一直在遇到这个最常见的错误)。 - FlipperBizkut
你不需要实现重试逻辑来获取重复键错误。例如,如果您以并发方式提交具有多个关系的大型对象,我会深入挖掘代码,看看重复键错误确切发生在哪里,并尝试找出限制它们的方法。除了重试策略外,网络错误几乎无法做什么。 - Etienne

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