2
我有一个转换,似乎没有回滚,并得到一个奇怪的错误。我正在使用与代码在同一服务器上的不同服务器上的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()
我不知道我在做什么错,什么是造成这个问题。我似乎无法生成这种相同的异常,并且我生成的每个异常都始终回滚。任何人都知道我可能会怎样产生这个错误?
感谢大家的帮助!
是的,DTC正在所有服务器上运行。提交和回滚似乎正在工作,除了这个例外。这几乎就像是事务正在创建,但不知何故在MSMQ.Send调用之前被删除,这是错误的原因。由于交易已被移除,因此第一部分承诺是单一交易。或者TransactionScope吃了一个异常,所以它从来没有真正成为事务的一部分,所以第一部分承诺是因为它是一个单独的事务,当调用MSMQ.Send时,它检测到没有事务,这就是错误的原因。 – 2010-10-19 14:25:55
看到我的更新另一件事尝试。有些事情导致数据库调用或MSMQ发送无法登记在事务处理事务中。 – 2010-10-19 14:38:28
在构造函数对象中创建的线程已被多个线程使用。考虑一下,这可能是一个问题。现在我想到了,它发生在服务器上有负载时。 – 2010-10-19 14:50:12