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
);
;)
感謝。それはある程度助けました...正常な同期ASP MVC 5コントローラメソッドのためにうまくいきます:AmbientTransactionContext.Currentはコントローラ呼び出しの前後で同じです。しかし、コントローラメソッドが 'async Task'で、 'await Bus.Publish(msg)'を実行すると、Controller呼び出しの後にAmbientTransactionContext.CurrentはNULLになります。 AmbientTransactionContext.Currentは、HTTPモジュールbegin/end-requestで管理されます。 –
"AmbientTransactionContext.CurrentはHTTPモジュールのbegin/end-requestで管理されています" ... ASP.NETは面白い時にスレッドを切り替えることが知られていますが、Web要求ハンドラは、HTTPモジュールと同じ実行コンテキストで実行されます。あなたはおそらく文脈を確立する別の場所を選択する必要があります – mookid8000
さて、私は考えを得る。 HttpContext.Current.Itemsにコンテキストを格納するようにリファクタリングしました。 Rebusの中にAmbientTransactionContext.Currentを見て、何かが失敗しているのではないかと思いますが? 1つのリクエストで2つのBus.Publish()を実行すると、Publish()内のコードに2つの異なるトランザクションが表示されますか? –