Транзакция не откатывается - PullRequest
2 голосов
/ 19 октября 2010

У меня есть переход, который, кажется, не откатывается и не получает странную ошибку. Я использую транзакцию, которая подключена к SQL Server 2008 на другом сервере и MSMQ на том же сервере, что и код. Вот пример кода:

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);
    }

Когда это происходит, все до того, как SendTransactionMsmqMsg не откатывается. Это случается очень редко. Вот некоторые из трассировок стека:

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()

Я не уверен, что я делаю неправильно и что вызывает эту проблему. Кажется, я не могу сгенерировать это же исключение, и каждое сгенерированное мной исключение всегда откатывается назад. Кто-нибудь знает, как я могу вообще сгенерировать эту ошибку?

спасибо за помощь всем!

1 Ответ

1 голос
/ 19 октября 2010

Работает ли DTC на всех серверах, участвующих в работе, выполняемой внутри транзакции? Все ли процессы имеют к нему надлежащий доступ?

Это сообщение имеет то же сообщение об ошибке, которое вы получаете: Membership.GetUser () в TransactionScope создает исключение TransactionPromotionException

Обновление

Где создается объект очереди сообщений? Я бы попытался создать его экземпляр внутри области транзакции.

...