.Net アプリケーションと COM+ オブジェクトの間でトランザクションを共有することはできますか?

StackOverflow https://stackoverflow.com/questions/21589

質問

しばらく前にいくつかのテストをしましたが、これを機能させる方法がわかりませんでした。

成分:

  • COM+ トランザクション オブジェクト (VB6 で開発)
  • IIS の .Net Web アプリケーション (トランザクションあり)
    COM+ コンポーネントを呼び出します
    SQLデータベースの行を更新します

テスト:

.Net アプリケーションを実行し、例外を強制します。

結果:

.Net アプリケーションから行われた更新はロールバックされます。
COM+ オブジェクトによって行われた更新はロールバックされません。

古い ASP ページから COM+ オブジェクトを呼び出すと、ロールバックが機能します。

「えっ?」と思う人もいるかもしれません。COM+ と .Net のことは頭がおかしいでしょう!」と思われがちですが、この世界には依然として COM+ コンポーネントが多数存在する場所がいくつかあります。私は、誰かがこれに直面したことがあるかどうか、そしてこれをうまく機能させる方法を見つけたかどうかに興味がありました。

役に立ちましたか?

解決

VB と .NET は異なる SQL 接続を使用するため (そして、ADO と ADO.NET が同じ接続を共有する方法はありません)、唯一の可能性は DTC (分散トランザクション コーディネーター) を利用することです。DTC は 2 つの独立したトランザクションを調整して、それらが一緒にコミットまたはロールバックされるようにします。

.NETから, EnterpriseServices は、DTC などの COM+ 機能を管理します。.NET 2.0 以降では、System.Transactions 名前空間を使用できるため、状況が少し良くなります。次のようなものが機能するはずだと思います(未テストのコード)。

void SomeMethod()
{
    EnterpriseServicesInteropOption e = EnterpriseServicesInteropOption.Full;
    using (TransactionScope s = new TransactionScope(e))
    {
        MyComPlusClass o = new MyComPlusClass();

        o.SomeTransactionalMethod();
    }
}

現時点ではこれ以上のアドバイスをできるほど詳しくありません。

COM+側, の場合、オブジェクトは分散トランザクションを使用する (おそらく「必須」) ように構成する必要があります。これは、COM+ エクスプローラーからオブジェクトの プロパティ, を選択して、 取引 タブをクリックし、「」をクリックします必須」。これをコードからも実行できるかどうかは覚えていません。VB6 は COM+ がリリースされる前に作成されたため、COM+ が行うすべての機能を完全にサポートしているわけではありません (トランザクション サポートは、MS Transaction Server と呼ばれる COM+ の前身向けのものでした)。

すべてが正しく動作する場合、COM+ オブジェクトは .NET コードによって作成された既存のコンテキストに参加しているはずです。

「コンポーネント サービス」の「分散トランザクション コーディネーター\トランザクション リスト」ノードを使用すると、呼び出し中に作成されている分散トランザクションを確認できます。

トランザクションがコミットされるまで、.NET 側からのデータ クエリに反映された COM+ コンポーネントからの変更を確認できないことに注意してください。実際、デッドロックが発生する可能性があります。DTC は 2 つのトランザクションがペアであることを確認しますが、依然として別個のデータベース トランザクションであることに注意してください。

他のヒント

これをどのように実装していますか?EnterpriseServices を使用して .NET トランザクションを管理している場合は、両方に同じコンテキストを使用しているため、両方のトランザクションがロールバックされるはずです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top