J'ai une transition qui ne semble pas annuler et obtenir une erreur étrange. J'utilise une transaction qui est connectée à SQL Server 2008 sur un serveur différent et MSMQ sur le même serveur que le code. Voici un exemple du code:La transaction ne recule pas
void MyMethod()
{
try
{
using (var outterTrans = new TransactionScope())
{
try
{
InsertA();
SendTransactionMsmqMsg(new BlahObject());
}
catch (Exception e)
{
//Exception is getting written here.
using (new TransactionScope(TransactionScopeOption.Suppress))
HandleException(e);
throw;
}
InsertB();
outterTrans.Complete();
}
}
catch(Exception e)
{
//Exception is getting written here too.
HandleException(e);
}
}
public void InsertA()
{
//Inserts data.
}
public void InsertB()
{
//Inserts data.
}
void SendTransactionMsmqMsg(object obj)
{
//When calling Msmq.Send I get 'The PROMOTE TRANSACTION request failed because there is no local transaction active.'
Msmq.Send(CreateMessage(obj), MessageQueueTransactionType.Automatic);
}
Lorsque cela se produit tout avant SendTransactionMsmqMsg ne soit roulé pas. C'est très rare que cela arrive aussi. Voici une partie de la trace de la pile aussi:
Type : System.Transactions.TransactionAbortedException, System.Transactions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Message : The transaction has aborted.
Source : System.Transactions
Help link :
Data : System.Collections.ListDictionaryInternal
TargetSite : Void CheckForFinishedTransaction(System.Transactions.InternalTransaction)
Stack Trace : at System.Transactions.TransactionStateAborted.CheckForFinishedTransaction(InternalTransaction tx)
at System.Transactions.EnlistableStates.Promote(InternalTransaction tx)
at System.Transactions.Transaction.Promote()
at System.Transactions.TransactionInterop.ConvertToOletxTransaction(Transaction transaction)
at System.Transactions.TransactionInterop.GetDtcTransaction(Transaction transaction)
at System.Messaging.MessageQueue.StaleSafeSendMessage(MQPROPS properties, IntPtr transaction)
at System.Messaging.MessageQueue.SendInternal(Object obj, MessageQueueTransaction internalTransaction, MessageQueueTransactionType transactionType)
at System.Messaging.MessageQueue.Send(Object obj, MessageQueueTransactionType transactionType)
********Functions from my code here********
Inner Exception
---------------
Type : System.Transactions.TransactionPromotionException, System.Transactions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Message : Failure while attempting to promote transaction.
Source : System.Data
Help link :
Data : System.Collections.ListDictionaryInternal
TargetSite : Byte[] Promote()
Stack Trace : at System.Data.SqlClient.SqlDelegatedTransaction.Promote()
at System.Transactions.TransactionStatePSPEOperation.PSPEPromote(InternalTransaction tx)
at System.Transactions.TransactionStateDelegatedBase.EnterState(InternalTransaction tx)
Inner Exception
---------------
Type : System.Data.SqlClient.SqlException, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Message : The PROMOTE TRANSACTION request failed because there is no local transaction active.
Source : .Net SqlClient Data Provider
Help link :
Errors : System.Data.SqlClient.SqlErrorCollection
Class : 16
LineNumber : 1
Number : 3965
Procedure :
Server : <machine>
State : 1
ErrorCode : -2146232060
Data : System.Collections.ListDictionaryInternal
TargetSite : Void OnError(System.Data.SqlClient.SqlException, Boolean)
Stack Trace : at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
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.Promote()
Je ne suis pas sûr de ce que je fais mal et de ce qui cause ce problème. Je n'arrive pas à générer cette même exception et chaque exception générée revient toujours en arrière. Quelqu'un sait comment je peux être capable de générer cette erreur du tout?
merci pour l'aide de tout le monde!
Oui, DTC est en cours d'exécution sur tous les serveurs. La validation et la restauration semblent fonctionner sauf avec cette exception. C'est presque comme si la transaction est créée, mais en quelque sorte être retiré avant l'appel MSMQ.Send et c'est la raison de l'erreur. Étant donné que la transaction a été supprimée, la première partie a été validée car il s'agissait d'une transaction unique. Ou TransactionScope a mangé une exception de sorte qu'elle n'a jamais vraiment fait partie d'une transaction, donc la première partie a été validée car il s'agit d'une transaction unique et lors de l'appel de MSMQ.Envoyer n'a détecté aucune transaction et c'est la raison de l'erreur. –
Voir ma mise à jour pour une autre chose à essayer. Quelque chose provoque soit l'appel de base de données ou l'envoi MSMQ pour ne pas inscrire dans la transaction transactionscope. –
Il est créé dans l'objet constructeur est utilisé par plus d'un thread. En y réfléchissant, cela peut être un problème. Maintenant que j'y pense, ça arrive quand il y a une charge sur le serveur. –