6

この投稿の根底にある質問は、「プロモーションされていない LTM トランザクションが疑わしいのはなぜですか?」ということです。

System.Transactions.TransactionInDoubtException が発生しましたが、その理由を説明できません。残念ながら、この問題を再現することはできませんが、トレース ファイルによると発生します。私は SQL 2005 を使用しており、1 つのデータベースに接続し、1 つの SQLConnection を使用しているため、プロモーションが行われるとは考えていません。エラー メッセージはタイムアウトを示します。ただし、タイムアウト メッセージが表示されることもありますが、例外は、トランザクションが未確定ではなく中止されたことです。これは、処理がはるかに簡単です。

完全なスタック トレースは次のとおりです。

System.Transactions.TransactionInDoubtException: トランザクションは未確定です。---> System.Data.SqlClient.SqlException: タイムアウトが発生しました。操作が完了する前にタイムアウト期間が経過したか、サーバーが応答していません。
   System.Data.SqlClient.SqlInternalConnection.OnError (SqlException 例外、ブール値の breakConnection) で
   System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning (TdsParserStateObject stateObj) で
   System.Data.SqlClient.TdsParserStateObject.ReadSniError (TdsParserStateObject stateObj、UInt32 エラー) で
   System.Data.SqlClient.TdsParserStateObject.ReadSni (DbAsyncResult asyncResult、TdsParserStateObject stateObj) で
   System.Data.SqlClient.TdsParserStateObject.ReadNetworkPacket() で
   System.Data.SqlClient.TdsParserStateObject.ReadBuffer() で
   System.Data.SqlClient.TdsParserStateObject.ReadByte() で
   System.Data.SqlClient.TdsParser.Run (RunBehavior runBehavior、SqlCommand cmdHandler、SqlDataReader dataStream、BulkCopySimpleResultSet bulkCopyHandler、TdsParserStateObject stateObj) で
   System.Data.SqlClient.TdsParser.TdsExecuteTransactionManagerRequest (Byte[] バッファー、TransactionManagerRequestType 要求、文字列 transactionName、TransactionManagerIsolationLevel isoLevel、Int32 タイムアウト、SqlInternalTransaction トランザクション、TdsParserStateObject stateObj、ブール値 isDelegateControlRequest) で
   System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransactionYukon (TransactionRequest transactionRequest、文字列 transactionName、IsolationLevel iso、SqlInternalTransaction internalTransaction、ブール値 isDelegateControlRequest) で
   System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransaction (TransactionRequest transactionRequest、文字列名、IsolationLevel iso、SqlInternalTransaction internalTransaction、ブール値 isDelegateControlRequest) で
   System.Data.SqlClient.SqlDelegatedTransaction.SinglePhaseCommit (SinglePhaseEnlistment 参加) で
   --- 内部例外スタック トレースの終了 ---
   System.Transactions.TransactionStateInDoubt.EndCommit (InternalTransaction tx) で
   System.Transactions.CommittableTransaction.Commit() で
   System.Transactions.TransactionScope.InternalDispose() で
   System.Transactions.TransactionScope.Dispose() で

何か案は?なぜ私は doubpt に入ってしまったのでしょうか?

詳細については編集

私は実際にはまだこれに対する答えを持っていません。私が気付いたのは、トランザクションが実際には部分的にコミットされているということです。1 つのテーブルは挿入されますが、もう 1 つのテーブルは更新されません。コードは非常にトレースされており、何かを見逃す余地はあまりありません。

取引が促進されたかどうかを簡単に確認できる方法はありますか。スタック トレースから確認できますか? SIngle フェーズ コミット (strack トレースにあります) は、昇進していないことを示しているようですが、何かが足りないのかもしれません。昇進していない場合、どうして疑わしいのでしょうか。

パズルのもう 1 つの興味深いピースは、現在のトランザクションのクローンを作成することです。この問題の回避策としてこれを行います。 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();
}

ありがとう

4

5 に答える 5

3

答えはそれができないということです。どうやら起こっていたのは、昇進が起こっていたということでした。(私たちは偶然これを発見しました)私はまだ昇進の試みが起こっているかどうかを検出する方法を知りません。それはこれを検出するのに非常に役に立ちました。

于 2010-08-27T14:36:43.863 に答える
0

コードを調べずにアドバイスするのは難しいですが、私の最初の提案は、1つの接続を持つ1つのSQLサーバーがある場合、TransactionScope()はオーバーヘッドであるということです。

代わりにSystem.Data.SqlClient.SqlTransaction()を使用しないのはなぜですか?

ドキュメントによると、「データベーストランザクション内でリモートサーバーへの接続が開かれると、リモートサーバーへの接続が分散トランザクションに参加し、ローカルトランザクションが自動的に分散トランザクションに昇格します。」ただし、実際に1つの接続のみを使用する場合は、非常に奇妙なエラーになります。MS SQL、MS MQ、または分散トランザクションの作成を必要とするその他のものへの接続を作成できるサードパーティコンポーネントを呼び出していないことを確認しますか?

また、SQL Server CLRプロシージャでTransactionScope()を使用すると、どのような場合でもトランザクションが促進されます。

また、リンクされたSQLサーバーからテーブルにアクセスするストアドプロシージャを呼び出す場合は、これにも昇格が必要になると思います。

質問はかなり古いものです。おそらくあなたはすでに答えを知っていて、他の人のためにここに投稿することができます。ありがとう!

于 2009-07-13T16:04:48.937 に答える
0

私は実際に同じ問題を抱えており、dbサーバーの仕様に関連しているようです。このコードを実行している間、データベース管理者にボックスの CPU 使用率を確認してもらいます。これは、トランザクション内でデータベース内の多数の行に対して更新操作を試行しているため、この環境で発生します。これは、最も使用頻度の高いテーブルの 1 つである OLTP データベースで発生しており、ロックの競合が発生します。この問題で興味深いのは、スタック トレースに見られるタイムアウトの側面です。コマンド上であろうと、TransactionScopeのコンストラクターへの引数としてであろうと、設定したタイムアウト値に関係なく、問題に対処していないようです。この問題に対処する方法は、コミットをチャンクすることです。お役に立てれば

于 2010-01-29T05:50:05.557 に答える
0

私を打ちのめします。

私は、「BEGIN TRANSACTION」と「COMMIT」または「ROLLBACK」で手動で ExecuteNonQuery を実行する習慣があります。

偶然にも、一部のコードがトランザクション内にあるかどうかに関係なく同じように動作する必要がある場合、これは非常にうまく機能しました。

于 2009-09-17T17:42:12.207 に答える