Как обрабатывать TransactionInDoubtException - PullRequest
3 голосов
/ 19 декабря 2011

У меня есть несколько простых SELECT операторов и INSERT, завернутый в блок using(TransactionScope...). ОБНОВЛЕНИЕ: уровень изоляции ReadCommited
я получил следующее исключение при вызове scope.Complete(). (см. ниже)
В то же время база данных находилась под высокой нагрузкой, вызванной другим приложением полностью.
После этого я обнаружил, что оператор INSERT действительно выполнен.

Мой вопрос: Как мне обработать это исключение таким образом, чтобы моя база данных находилась в согласованном состоянии?

Я ищу транзакцию, которая всегда либо завершена, либо не завершена и никогда не завершена наполовину.

Трассировка стека исключений:

System.Transactions.TransactionInDoubtException: The transaction is in doubt. ---> 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(TdsParserStateObject stateObj)
   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.SqlDelegatedTransaction.SinglePhaseCommit(SinglePhaseEnlistment enlistment)
   --- End of inner exception stack trace ---
   at System.Transactions.TransactionStateInDoubt.EndCommit(InternalTransaction tx)
   at System.Transactions.CommittableTransaction.Commit()
   at System.Transactions.TransactionScope.InternalDispose()
   at System.Transactions.TransactionScope.Dispose()

1 Ответ

3 голосов
/ 22 февраля 2012

Транзакция вызывает сомнения, когда неизвестно, была ли она завершена или прервана.База данных все еще находится в согласованном состоянии.Если вы когда-нибудь получите такое исключение, вам нужно получить доступ к базе данных, чтобы выяснить, произошли ли изменения, но вы можете быть уверены, что не увидите половину изменений.

Примечание, яне знаю, что произойдет, если сомнительным компонентом является DTC, и у вас есть распределенная транзакция - я надеюсь, что Microsoft позаботилась об этом, и что сомнительная распределенная транзакция по-прежнему рассматривается как единое целое.

См. Здесь: «В частности, конечный результат транзакции, независимо от того, фиксирует ли она транзакцию или прерывается, никогда не известен этой транзакции».

...