La question sous-jacente à cet article est "Pourquoi une transaction LTM non promue est-elle jamais mise en doute?"TransactionInDoubtException à l'aide de System.Transactions sur SQL Server 2005
Je reçois System.Transactions.TransactionInDoubtException et je ne peux pas expliquer pourquoi. Malheureusement, je ne peux pas reproduire ce problème, mais selon les fichiers de trace, cela arrive. J'utilise SQL 2005, en me connectant à une base de données et en utilisant une SQLConnection, donc je ne m'attends pas à une promotion. Le message d'erreur indique un délai d'expiration. Cependant, parfois, je reçois un message de délai d'attente, mais l'exception est que la transaction a avorté par opposition à un doute, ce qui est beaucoup plus facile à gérer.
Voici la trace complète de la pile:
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()
Toutes les idées? Pourquoi suis-je dans le doute et que dois-je faire quand je l'obtiens?
EDIT pour plus d'informations
En fait, je ne comprends toujours pas la réponse pour cela. Ce que je me suis rendu compte est que la transaction s'engage en partie partiellement. Une table reçoit l'insertion mais l'autre n'obtient pas la mise à jour. Le code est LOURDEMENT tracé et il n'y a pas beaucoup de place pour que je manque quelque chose.
Y at-il un moyen que je peux facilement savoir si la transaction a été promue. Pouvons-nous dire à partir de la trace de la pile si c'est le cas? La phase SIngle commit (qui est dans la trace de Strack) semble ne pas m'avoir donné de promotion, mais peut-être qu'il me manque quelque chose. Si ce n'est pas promu alors comment peut-il être dans le doute.
Une autre pièce intéressante au puzzle est que je crée un clone de la transaction en cours. Je fais cela comme un travail sur cette question. http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=914869&SiteID=1
Malheureusement, je ne sais pas si ce problème a été résolu. Peut-être que créer le clone cause un problème. Voici le code correspondant
using (TransactionScope ts = new TransactionScope())
{
transactionCreated = true;
//part of the workarround for microsoft defect mentioned in the beginning of this class
Transaction txClone = Transaction.Current.Clone();
transactions[txClone] = txClone;
Transaction.Current.TransactionCompleted += new TransactionCompletedEventHandler(TransactionCompleted);
MyTrace.WriteLine("Transaction clone stored and attached to event");
m_dataProvider.PersistPackage(ControllerID, package);
MyTrace.WriteLine("Package persisted");
m_dataProvider.PersistTransmissionControllerStatus(this);
MyTrace.WriteLine("Transmission controlled updated");
ts.Complete();
}
Merci
la base de données en miroir? –
Non, la base de données n'est pas mise en miroir. Cela ne se produit pas seulement dans un ou deux environnements mais dans des douzaines d'entre eux – Mark
Avez-vous essayé de demander sur [serverfault] (http://serverfault.com/)? Ou même en mettant une demande surport avec Microsoft. S'il vous plaît poster la réponse quand vous le trouvez ... –