Mar*_*ark 5 c# transactions sql-server-2005 transactionscope system.transactions
这篇文章的基本问题是"为什么非升级的LTM交易会受到质疑?"
我收到System.Transactions.TransactionInDoubtException,我无法解释原因.不幸的是我无法重现这个问题,但根据跟踪文件它确实发生了.我正在使用SQL 2005,连接到一个数据库并使用一个SQLConnection,所以我不希望进行促销.错误消息表示超时.但是,有时我得到一条超时消息,但异常是事务已中止而不是有疑问,这更容易处理.
这是完整的堆栈跟踪:
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()
有任何想法吗?为什么我会怀疑,当我得到它时我该怎么办?
编辑以获取更多信息
我实际上仍然没有这个答案.我所意识到的是交易实际上是部分提交的.一个表获取插入但另一个表未获得更新.代码是HEAVILY跟踪,没有太多空间让我错过一些东西.
有没有办法可以轻松找出交易是否已被提升.我们可以从堆栈跟踪中判断它是否存在?单一阶段提交(在strack trace中)似乎表明没有向我推广,但也许我错过了一些东西.如果它没有得到提升那么它怎么会有疑问.
这个难题的另一个有趣的部分是我创建了当前事务的克隆.我这样做是为了解决这个问题. http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=914869&SiteID=1
不幸的是,我不知道这个问题是否已经解决.也许创建克隆会导致问题.这是相关的代码
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();
}
Run Code Online (Sandbox Code Playgroud)
谢谢
Bat*_*ech 12
目前接受的答案是,非升级的LTM(非MSDTC)交易永远不会有疑问.经过对类似问题的大量研究后,我发现这是不正确的.
由于单阶段提交协议的实现方式,在事务管理器将SinglePhaseCommit请求发送给其下级之后,以及在下级回复之前,事务处于"怀疑"状态的时间很短.中止/或准备(需要推广/升级到MSDTC)消息.如果在此期间连接丢失,则事务处于"不确定"状态,b/c当TransactionManager要求下属执行SinglePhaseCommit时,它从未收到响应.
从MSDN单阶段提交,还可以在此答案的底部看到"单阶段提交流"图像:
这种优化有一个可能的缺点:如果事务管理器在发送单阶段提交请求之后但在接收结果通知之前失去与下级参与者的联系,则它没有可靠的机制来恢复事务的实际结果.因此,事务管理器向等待信息结果通知的任何应用程序或选民发送In Inouboub结果
这里还有我发现的一些实际例子,它们会导致System.Transaction升级/升级到MSDTC事务(这与OP没有直接关系,但我发现它非常有用.在VS 2013中测试过,SQL Server 2008 R2 ,.NET 4.5除非另有说明):
以下是导致升级的MS正式列表:http://msdn.microsoft.com/en-us/library/ms229978( v = vs.85).aspx

答案是不能。显然正在发生的事情是促销正在进行中。(我们无意中发现了这一点)我仍然不知道如何检测是否正在发生促销尝试。这对于检测这一点非常有用。
| 归档时间: |
|
| 查看次数: |
9771 次 |
| 最近记录: |