使用实体框架,我昨晚在我的一个应用程序中收到了以下一些异常:
System.Data.EntityException: The underlying provider failed on Commit. --->
System.Data.SqlClient.SqlException: Timeout expired. The timeout period elapsed prior
to completion of the operation or the server is not responding.
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
at System.Data.SqlClient.TdsParserStateObject.ReadSniError(TdsParserStateObject stateObj, UInt32 error)
at System.Data.SqlClient.TdsParserStateObject.ReadSni(DbAsyncResult asyncResult, TdsParserStateObject stateObj)
at System.Data.SqlClient.TdsParserStateObject.ReadNetworkPacket()
at System.Data.SqlClient.TdsParserStateObject.ReadBuffer()
at System.Data.SqlClient.TdsParserStateObject.ReadByte()
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler,SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
at System.Data.SqlClient.TdsParser.TdsExecuteTransactionManagerRequest(Byte[] buffer, TransactionManagerRequestType request, String transactionName, TransactionManagerIsolationLevel isoLevel, Int32 timeout, SqlInternalTransaction transaction, TdsParserStateObject stateObj, Boolean isDelegateControlRequest)
at System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransactionYukon(TransactionRequest transactionRequest, String transactionName, IsolationLevel iso, SqlInternalTransaction internalTransaction, Boolean isDelegateControlRequest)
at System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransaction(TransactionRequest transactionRequest, String name, IsolationLevel iso, SqlInternalTransaction internalTransaction, Boolean isDelegateControlRequest)
at System.Data.SqlClient.SqlInternalTransaction.Commit()
at System.Data.SqlClient.SqlTransaction.Commit()
at System.Data.EntityClient.EntityTransaction.Commit()
--- End of inner exception stack trace ---
at System.Data.EntityClient.EntityTransaction.Commit()
at System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options)
at System.Data.Entity.Internal.InternalContext.SaveChanges()
at System.Data.Entity.Internal.LazyInternalContext.SaveChanges()
这个错误的有趣之处在于数据实际上被写入了数据库。我在微软网站上发现了一个相关的帖子,似乎表明这是一个网络相关的错误。
我需要帮助的几个问题是:
- 我有什么选项来解决这个错误?
- 它更可能是网络相关的还是DB可能是一个嫌疑人?
- 我如何从代码中判断事务是否真正完成?
- 我应该在此错误上查询DB以检查是否成功或简单地重试事务?
- 如果我重试事务,如何使用实体框架自动完成,或者我只是捕获/重试?
- 我还应该看哪些项目?
提前感谢。
使用Ignite for SQL,我们能够确定来自另一个组的次要SQL进程独占CPU,从而阻止我们的应用程序正常运行。简而言之,我们正在增加一个辅助服务器,以防止两个团队之间进一步的冲突。
异常的有趣之处在于事务实际上是成功的,而不是失败的。
我敢打赌,来自事务提交命令的成功响应没有发送(或者发送得不够快),导致代码中出现异常。有点疯狂的边缘情况。这种异常并不一定意味着命令的实际执行失败,只是有一个失败。
同样,如果从webservice调用发送响应出现问题,这并不一定意味着该调用没有应用任何副作用。
+1对于Luke来说,这个解释是好的。错误的措辞是不幸的。
System.Data.EntityException: **The underlying provider failed on Commit.** --->
System.Data.SqlClient.SqlException: Timeout expired. The timeout period elapsed prior
应读作
System.Data.EntityException: **The underlying provider failed to respond to Commit**
System.Data.SqlClient.SqlException: Timeout expired. The timeout period elapsed prior
可能的原因是网络或服务器问题。例如100个CPU,或其他服务器延迟,都是正确的。但是你不知道它是否已经提交,如果这是一个超时的情况。如果收到的响应是失败的,则DB应该已经回滚。当然,如果没有发生这种情况,那么DB就会崩溃,并导致潜在的腐败。我希望是罕见的。
我在一个超过10亿行的表中见过…在增长下的空间分配过程中,由于索引和数据区域需要扩展,需要30秒以上。但是提交确实发生了。客户端已超时。在线重组也会导致这样的延迟(至少我在DB2上看到过这种情况)