Подтвердить что ты не робот

Исправление System.Data.EntityException: основной провайдер отказался от Commit

Используя 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()

Что интересно об этой ошибке, так это то, что данные были фактически записаны в базу данных. я нашел связанный пост на сайте MS, который, казалось, указывал на то, что это была связанная с сетью ошибка.

Несколько вопросов, которые я мог бы использовать, это:

  • Какие параметры у меня есть, чтобы устранить эту ошибку?
  • Возможно, это связано с сетью или может быть причиной подозрения DB?
  • Как я могу узнать из кода, действительно ли транзакция действительно завершилась?
  • Должен ли я запрашивать БД для этой ошибки, чтобы проверить успешность или просто повторить транзакцию?
  • Если я повторю транзакцию, как это может быть выполнено автоматически с помощью Entity Framework или я просто поймаю/повторю?
  • На какие еще предметы я должен смотреть?

Спасибо заранее.

UPDATE

Используя Ignite for SQL, мы смогли определить, что вторичный SQL-процесс из другой группы монополизировал процессор, препятствуя правильному функционированию нашего приложения. Короче говоря, мы продвигаемся вперед, добавляя дополнительный сервер, чтобы предотвратить дальнейшие конфликты между двумя командами.

Что все еще интересно об исключении, так это то, что транзакция действительно преуспела, а не неудалась.

4b9b3361

Ответ 1

Моя ставка заключается в том, что ответ успеха от команды фиксации транзакции не был отправлен (или не отправлен достаточно быстро), вызвав исключение в вашем коде. Это своего рода сумасшедший край. Исключения такого рода не обязательно означают, что фактическое выполнение команды завершилось неудачей, только что произошел сбой.

Таким же образом, если возникла проблема с отправкой ответа из вызова webservice, это не обязательно означает, что любые побочные эффекты этого вызова не были применены.

Ответ 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 или другая задержка сервера, все еще верны. НО вы НЕ ЗНАЕТЕ, если он совершил или нет, если это тайм-аут. Если ответ был получен с ошибкой, БД должна была вернуться назад. Конечно, если это не произошло, тогда БД разрушила ummm и привела к потенциальной коррупции. Редкий я надеюсь.

Я видел в таблице 1 миллиард + строк... При распределении пространства при росте, так как область индексов и данных нуждается в расширении, потребуется более 30 секунд. НО СОСТОЯЛОСЬ. Клиент был отключен. Онлайн-реорганизации также могут вызывать такие задержки (хорошо видно, что по крайней мере на DB2)