1

次のコード ベースは、Windows Server、Windows XP で何年も機能し、Windows 7 では信頼できなくなりました。

呼び出し元と呼び出し先の 2 つの COM+ コンポーネントは、同じトランザクション コンテキストを共有し、間接再帰に参加します。呼び出し元は最初に呼び出し先を複数回呼び出し、呼び出し先は常に最終的にSetCompleteまたはSetAbort戻る前に呼び出します (これが呼び出し元 -> 呼び出し先呼び出しであるか、呼び出し元 -> 呼び出し先 -> 呼び出し元 -> 呼び出し先であるかに関係なく)。

私が見ているのは、呼び出し先の 2 番目の呼び出し内の最初の SQL クエリが次のようにエラーになることです。

分散トランザクションが完了しました。このセッションを新しいトランザクションまたは NULL トランザクションに参加させる

一部の構成では、トランザクションは非常に遅く、60 秒を簡単に超える可能性があります。

SetCompleteこのエラーは、トランザクション タイムアウトのように見えます。または、完了ビットを設定している疑いのあるコンポーネントの非アクティブ化の可能性があります。ただし、それはトランザクションのルート コンポーネントではなく、このドキュメントには「ただし、SetAbort を呼び出しているオブジェクトがトランザクションのルートでない限り、最終的にアボートすることを防ぐものは何もなくても、トランザクションは引き続き実行されます。」 と明確に記載されています。 「トランザクションのルートオブジェクトが非アクティブ化されるまで、トランザクションはコミットも中止もされません。 」したがって、何らかの形でエラーに寄与している可能性があるかどうかはわかりません。SetComplete

インストール時にすべてのコンポーネントのトランザクション タイムアウトがコンポーネント レベルで 1800 秒に設定され、グローバル トランザクション タイムアウトが 60 秒に設定されます。SqlClientコンポーネントは、ほとんどの場合、データベース アクセスに ADO (切断された結果セットを含む) または .NETを使用します。

私が見ているもののいくつかの側面を理解していません。

  1. 同じコンポーネントの複数のインスタンスが同じトランザクションで同時にSetCompleteアクティブになっている場合、呼び出し元のインスタンス以外のインスタンスが早期に非アクティブ化されSetCompleteたり、トランザクション タイムアウトの適用規則に影響したりする可能性はありますか?
  2. Windows 7 は、他のいくつかの OS とは異なる方法で (より速く) コンポーネントを非アクティブ化しますか? この動作を制御する構成はありますか。
  3. Windows 7 がコンポーネント レベルのトランザクション タイムアウトを無視する可能性はありますか? そのような欠陥はずっと前にありました。
4

1 に答える 1

0

質問に対して良い洞察を提供してくれる人には、喜んで賞金を授与します。しかし、私たちの最初の問題はこれまで追跡されました。

(不幸な同期と再試行ロジックのために)60秒強かかることがほぼ保証されている特定の非常に長時間実行されるトランザクションが見つかりました。そのトランザクションコンテキストは、他のコードベースとは異なり、手動で作成され、Windows 7でグローバルトランザクションタイムアウトを継承していました。ただし、すべてのコンポーネント内で実行すると、宣言型トランザクション時間が1800秒に設定されます。これが他のオペレーティングシステムでまだ機能する理由はあまり明確ではありませんが、もちろん、この長期にわたるトランザクションシナリオ全体を排除しています。

これが、上記の「手動で作成」の意味です。

_COM_SMARTPTR_TYPEDEF(ITransactionContextEx, __uuidof(ITransactionContextEx));
ITransactionContextExPtr pTransContext;
TESTHR(pTransContext.CreateInstance(CLSID_TransactionContextEx));

ISomeSvcsPtr pSomeSvcs;

pTransContext->CreateInstance(__uuidof(PSSomeSvcs), 
                              ISomeSvcsPtr::GetIID(), 
                              reinterpret_cast<void **>(&pSomeSvcs));
于 2013-02-08T10:09:06.137 に答える