2016-11-03 4 views
1

Web/SOAPサービスがあるとすれば、Rebus(メッセージングバス)の適切なトランザクションコンテキストを設定および解除するにはどうすればよいですか? Rebusがメッセージハンドラを呼び出すとき、Rebusはハンドラを呼び出す前にトランザクションコンテキストを設定するので問題はありませんが、WebサービスハンドラがRebus経由でメッセージを送信/発行する必要がある場合はどうなりますか?WebサービスのRebusトランザクションコンテキストを設定する方法

HTTPモジュールなどを実装する方法には興味がありません.Rebusの基本について:メッセージを送信するためにRebusを準備するには何が必要ですか?

Webサービスコードには、アプリケーションデータベースと通信するときに実行される独自のトランザクションがあります。私は、データベーストランザクションを設定するときにRebusを設定し、データベースと同じことをするときにReitをコミット/ロールバックする必要があります。

私は、データベースとのやり取りとRebusメッセージの送信の両方を必要とするスタンドアロンのコマンドラインプログラムでも同様の問題があります。

答えて

1

Rebusは、静的(*)AmbientTransactionContext.Currentプロパティを介してアクセスする独自の「アンビエントトランザクションコンテキスト」で、送信およびパブリッシュ操作を自動的に登録します。

あなたは自分でITransactionContextを実装できますが、RebusにはボックスにDefaultTransactionContextが付いています。

あなたはこのようにそれを使用します。簡単に、例えば置くことができ

using(var context = new DefaultTransactionContext()) 
{ 
    AmbientTransactionContext.Current = context; 

    // send and publish things in here 

    // complete the transaction 
    await context.Complete(); 
} 

OWINミドルウェアまたはそれに類するもの


(*)プロパティは静的ですが、根本的な値は、あなたがその素晴らしい特性と、スレッドに結びついたと考えることができますことを意味し、(CallContext.LogicalGet/SetDataを使用して)現在の実行コンテキストにバインドされています期待通りに継続に流れる。

Rebus 2.0.2では、Action<ITransactionContext>Func<ITransactionContext>を持つAmbientTransactionContext.SetAccessors(...)を呼び出して、コンテキストを取得/設定するために使用するアクセサをカスタマイズすることができます。このような:

この場合には、それは古い学校のHTTPモジュールを使用する場合であっても、適切に流れるように動作します
AmbientTransactionContext.SetAccessors(
    context => { 
     if (HttpContext.Current == null) { 
      throw new InvalidOperationException("Can't set the transaction context when there is no HTTP context"); 
     } 
     HttpContext.Current.Items["current-rbs-context"] = context 
    }, 
    () => HttpContext.Current?.Items["current-rbs-context"] as ITransactionContext 
); 

;)

+0

感謝。それはある程度助けました...正常な同期ASP MVC 5コントローラメソッドのためにうまくいきます:AmbientTransactionContext.Currentはコントローラ呼び出しの前後で同じです。しかし、コントローラメソッドが 'async Task 'で、 'await Bus.Publish(msg)'を実行すると、Controller呼び出しの後にAmbientTransactionContext.CurrentはNULLになります。 AmbientTransactionContext.Currentは、HTTPモジュールbegin/end-requestで管理されます。 –

+0

"AmbientTransactionContext.CurrentはHTTPモジュールのbegin/end-requestで管理されています" ... ASP.NETは面白い時にスレッドを切り替えることが知られていますが、Web要求ハンドラは、HTTPモジュールと同じ実行コンテキストで実行されます。あなたはおそらく文脈を確立する別の場所を選択する必要があります – mookid8000

+0

さて、私は考えを得る。 HttpContext.Current.Itemsにコンテキストを格納するようにリファクタリングしました。 Rebusの中にAmbientTransactionContext.Currentを見て、何かが失敗しているのではないかと思いますが? 1つのリクエストで2つのBus.Publish()を実行すると、Publish()内のコードに2つの異なるトランザクションが表示されますか? –

関連する問題