正如您已經正確發現的那樣,Rebus版本> = 0.90.0不會自動在環境事務中登記。
(UPDATE:爲0.99.16,所期望的行爲就可以了 - 看到這個答案的詳細信息,到底如何)
然而,這並不意味着滷麪不能在一個事務中登記 - 它只是使用自己的環境事務機制(不依賴於System.Transactions
,並且在Rebus移植到.NET核心時可用)。
您可以使用滷麪DefaultTransactionContext
和‘使其環境’這一AmbientRebusTransactionContext
:
/// <summary>
/// Rebus ambient transaction scope helper
/// </summary>
public class AmbientRebusTransactionContext : IDisposable
{
readonly DefaultTransactionContext _transactionContext = new DefaultTransactionContext();
public AmbientRebusTransactionContext()
{
if (AmbientTransactionContext.Current != null)
{
throw new InvalidOperationException("Cannot start a Rebus transaction because one was already active!");
}
AmbientTransactionContext.Current = _transactionContext;
}
public Task Complete()
{
return _transactionContext.Complete();
}
public void Dispose()
{
AmbientTransactionContext.Current = null;
}
}
然後你就可以使用這樣的:
using(var tx = new AmbientRebusTransactionContext())
{
await bus.Send(new Message());
await tx.Complete();
}
,或者,如果你使用它在一個web應用程序中,我建議你把它包裝在這樣的OWIN中間件中:
app.Use(async (context, next) =>
{
using (var transactionContext = new AmbientRebusTransactionContext())
{
await next();
await transactionContext.Complete();
}
});
UPDATE:既然滷麪0.99.16,下面已經支持(通過Rebus.TransactionScope
包):
using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
scope.EnlistRebus(); //< enlist Rebus in ambient .NET tx
await _bus.SendLocal("hallå i stuen!1");
scope.Complete();
}
這種做法是確定的,如果我想在滷麪TransactionContext爭取。但是,如何參與.Net System.Transactions?在我看來,它是安靜的常見情況,當你在.net Transactionscope中執行商業邏輯並且執行** bus時。發送**作爲這個範圍的一部分 –
我繼續並實現了你所要求的 - 現在你可以調用'scope.EnlistRebus();'創建一個事務範圍以在範圍內引入一個環境Rebus事務 - 請記住'TransactionScopeAsyncFlowOption.Enabled'選項! – mookid8000
在等待您的回覆時,我已經實現了自己的包裝,它的工作方式與舊時尚AmbientTransactionContext:IEnlistmentNotification,ITransactionContext和新的AmbientTransactionBridge一樣。但是開箱即用的支持是* PERFECT *。可能是時候更新[github Wiki](https://github.com/rebus-org/Rebus/wiki/Transactions):) –