2015-11-26 52 views
3

這在以前滷麪的(< = 0.84.0)版本中的TransactionScope發送的信息是可能的,如果範圍完成滷麪送在TransactionScope的

using (var scope = new TransactionScope()) 
{ 
    var ctx = new AmbientTransactionContext(); 
    sender.Send(recipient.InputQueue, msg, ctx); 

    scope.Complete(); 
} 

是否有可能才達到同樣的也就只有送在Rebus2中的行爲

回答

2

正如您已經正確發現的那樣,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(); 
} 
+1

這種做法是確定的,如果我想在滷麪TransactionContext爭取。但是,如何參與.Net System.Transactions?在我看來,它是安靜的常見情況,當你在.net Transactionscope中執行商業邏輯並且執行** bus時。發送**作爲這個範圍的一部分 –

+1

我繼續並實現了你所要求的 - 現在你可以調用'scope.EnlistRebus();'創建一個事務範圍以在範圍內引入一個環境Rebus事務 - 請記住'TransactionScopeAsyncFlowOption.Enabled'選項! – mookid8000

+1

在等待您的回覆時,我已經實現了自己的包裝,它的工作方式與舊時尚AmbientTransactionContext:IEnlistmentNotification,ITransactionContext和新的AmbientTransactionBridge一樣。但是開箱即用的支持是* PERFECT *。可能是時候更新[github Wiki](https://github.com/rebus-org/Rebus/wiki/Transactions):) –