【问题标题】:System.Data.EntityException: The underlying provider failed on CommitSystem.Data.EntityException:底层提供程序在提交时失败
【发布时间】:2011-12-08 12:25:10
【问题描述】:

使用 Entity Framework,我昨晚在我的一个应用程序中收到了以下一些异常:

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()

这个错误的有趣之处在于数据实际上已写入数据库。我found a related post on a MS site 似乎表明这是一个与网络相关的错误。

我可以帮助解决的几个问题是:

  1. 我有哪些选项可以解决此错误?
  2. 很可能与网络有关还是数据库可能是嫌疑人?
  3. 如何从代码中判断交易是否真的完成了?
  4. 我应该在这个错误上查询数据库以检查是否成功或只是重试事务?
  5. 如果我确实重试了事务,如何使用 Entity Framework 自动完成,或者我只是捕获/重试?
  6. 我还应该查看哪些其他项目?

提前致谢。

更新

使用Ignite for SQL,我们能够确定来自另一个组的辅助 SQL 进程正在独占 CPU,从而阻止我们的应用程序正常运行。简而言之,我们正在继续添加辅助服务器,以防止两个团队之间进一步发生冲突。

这个异常的有趣之处在于事务实际上是成功而不是失败。

【问题讨论】:

  • 我知道这已经很久了,但是您能详细说明一下您是如何使用 Ignite for SQL 的吗?就我而言,它并不总是发生,因此很难知道何时观看服务器。
  • 不能说我是点燃大师;我们有一个数据库性能团队来处理这些事情。我可以说,当我遇到性能问题时,我通常会寻找顶级 sql 语句(如点燃状态“大条”)。这些通常是占用一切的查询。从那里开始调整这些查询。抱歉,我无法提供您正在寻找的更多细节。祝你好运。

标签: .net sql-server entity-framework transactions sqlclient


【解决方案1】:

我敢打赌,来自事务提交命令的成功响应未发送(或发送速度不够快)导致您的代码出现异常。有点疯狂的边缘案例。这种异常并不一定意味着该命令的实际执行失败只是发生了A失败。

同样,如果从 Web 服务调用发送响应时出现问题,也不一定意味着该调用的任何副作用都没有应用。

【讨论】:

  • 卢克,感谢您的评论。你绝对有正确的想法。我在 WS 代码中看到了同样的情况,其中 WS 处理了请求但响应超时。发生这种情况时让我发疯,因为您无法“知道”事情是否真的有效;除非您想编写可以调用的服务来验证事情是否确实有效。 ;-)
  • @Randy 实际上与使用 TCP 的计算机网络非常相似。原则是,如果我们没有得到消息已传递的确认,我们会重试它,直到我们这样做,但这意味着消息(在本例中为数据库事务)必须是幂等的(即可重播),但情况并非如此数据库事务
【解决方案2】:

卢克+1,解释很好。 错误的措辞令人遗憾。

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 或其他服务器延迟仍然是正确的。但是你不知道它是否已经提交,如果这是一个超时情况。 如果收到失败的响应,则数据库应该已回滚。当然,如果这没有发生,那么数据库已经崩溃并导致潜在的损坏。我希望很少见。

我在一个 10 亿多行的表中看到...在增长的空间分配过程中,由于索引和数据区域需要扩展,需要 30 多秒。但是 COMMIT 确实发生了。客户端已超时。在线重组也会导致这样的延迟(我至少在 DB2 上看到过)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-23
    • 2011-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多