関連する質問と実装された提案をよく調べましたが、.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ページの背後にあるコードを介して開始されています。