0

関連する質問と実装された提案をよく調べましたが、.NETTransactionScopeにまだ問題があります。

メソッドから2つのWCFサービスを呼び出していますが、2番目のサービスエラー(この場合は意図的に)が発生しても、最初のサービスはロールバックされません。問題を実証するための簡単なテストアプリケーションを作成しました。

呼び出しメソッドは次のとおりです。

private void TryATransaction()
{
    ServiceReference1.IService1 service = new ServiceReference1.Service1Client();
    ServiceReference2.IService1 service2 = new ServiceReference2.Service1Client();

    using (TransactionScope scope = new TransactionScope())
    {
        service.TestMethod("one");
        service2.UpdateSomethingElse("two");

        scope.Complete();
    }
}

最初のサービスは次のようになります(接続は匿名になります):

public bool TestMethod(string anything)
{
        using (TransactionScope scope = new TransactionScope())
        {

            // connect to a db
            using (SqlConnection connection = new SqlConnection("Data Source=DATASOURCE;Initial Catalog=DATABASE;Integrated Security=SSPI;Transaction Binding=Explicit Unbind;"))
            {

                connection.Open();
                // save something
                SqlCommand command1 = new SqlCommand("EXECUTE [DATABASE].[dbo].[uspUpdateCustomer] 3, 'test@test.com', 1, null", connection);
                command1.ExecuteNonQuery();
                connection.Close();

            }

            scope.Complete();
        }

    return true;
}

また、2番目のサービスは、データベース内の別のフィールドを更新することを除いて、最初のサービスと同じです。

1)エラーを強制せずにこれを実行すると、すべてのフィールドが正常に更新されます。

2)これを実行して2番目のサービスでエラーを強制すると、最初のサービスからの更新がデータベースにコミットされ、2番目のサービスがロールバックされます(エラーはExecuteNonQueryステートメントの後であります)。

このサンプルコードは、基本的にここにある例に従います:http: //msdn.microsoft.com/en-us/library/system.transactions.transactionscope.aspx

また、他の関連する質問で推奨されているExplicitUnbindを追加しました。

ご提案は大歓迎です。必要に応じて、さらに情報を追加させていただきます。

追加情報

配布された識別子は常に00000000-0000-0000-0000-000000000000のようです-これが手がかりかどうかはわかりません。

これが分散IDとローカルIDのdubug出力です(この順序で)

現在のトランザクションは00000000-0000-0000-0000-000000000000-f6446876-496d-488c-a21c-1e4c4295d50c:8

現在のトランザクションは00000000-0000-0000-0000-000000000000-7edd5ba3-7f5a-42af-b9ca-37b3862c26a7:2です。

現在のトランザクションは00000000-0000-0000-0000-000000000000-6fa0e3f7-b655-40ad-8bdd-f0670de79a49:2です。

トランザクションは、私のサンプルアプリのaspxページの背後にあるコードを介して開始されています。

4

1 に答える 1

1

編集:申し訳ありませんが、物事が逆でした。

ほとんどの場合、問題は WCF と共にトランザクションを使用することが原因です。

トランザクション サービスに関するこの記事を参照してください。特に、クライアント/サービス モードのトランザクションに関する部分。

基本的に、次のことを行う必要があります。

  • [TransactionFlow(TransactionFlowOption.Mandatory)]OperationContract インターフェイス メソッドに属性を設定する
  • [OperationBehavior(TransactionScopeRequired = true)]実装に属性を設定します
  • TransactionFlowBindingElementサービスの BindingContext に を追加します
  • TransactionScopeクライアントの TransactionScope を使用しているため、サービスの実装から を削除します。

正常に完了した各サービス メソッドは、トランザクションの成功を投票します (デフォルトの TransactionAutoComplete=true OperationBehavior を使用している場合)。

例外が原因でサービス メソッドが失敗した場合、トランザクションの失敗に投票します。

于 2009-11-26T09:25:04.020 に答える