2010-10-18 4 views
2

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!

Répondre

1

Le DTC s'exécute-t-il sur tous les serveurs impliqués dans le travail effectué dans la transaction? Tous les processus ont-ils un accès approprié?

Ce message a le même message d'erreur que vous obtenez: Membership.GetUser() within TransactionScope throws TransactionPromotionException

Mise à jour

Où est l'objet de file d'attente de messages instancié? J'essaierais de l'instancier à l'intérieur de la portée de la transaction.

+0

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. –

+0

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. –

+0

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. –

Questions connexes