2014-04-08 75 views
1

比方說,我們有如下的業務規則交易範圍界定:同步命令/事件處理程序(在NServiceBus)

  1. 當一個訂單被取消,所有未發貨的出貨量應該 取消。
  2. 個別運輸可能因其他原因被取消。

如果我們做同步這個東西,我對交易範圍的問題:

  1. 我聽到有人說,總結==「事務邊界」,但不會是更在這種情況下有利於請求範圍的DbContext,以便所有同步處理程序都在相同的事務中執行?如果後面的兩個處理者失敗了,它會給予更多的一致性。
  2. 如果#1不是一個好主意,爲什麼?我們只是說「每個處理者在自己的交易中,如果中間出現問題,你就自己處理了」?
  3. 如果#1是一個好主意,我該怎麼做NServiceBus'Bus.InMemoryThe documentation在這個問題上不是很清楚。

代碼如下:

public class CancelOrder : ICommand 
{ 
    public Guid Id { get; set; } 
} 

public class OrderCancelled : IEvent 
{ 
    public Guid Id { get; set; } 
} 

public class CancelShipment : ICommand 
{ 
    public Guid Id { get; set; } 
} 

public class CancelOrderHandler : IHandleMessages<CancelOrder> 
{ 
    private DbContext _dbContext; 
    private IBus _bus; 

    public void Handle(CancelOrder message) 
    { 
     var order = _dbContext.Orders.Single(x => x.Id == message.Id); 

     // do some validation here 

     order.Status = OrderStatus.Cancelled; 

     // unsure about whether to call _dbContext.SaveChanges() or not 

     _bus.Publish(new OrderCancelled { 
      Id = message.Id 
     }); 
    } 
} 

public class OrderCancelledHandler : IHandleMessages<OrderCancelled> 
{ 
    private DbContext _dbContext; 
    private IBus _bus; 

    public void Handle(CancelOrder message) 
    { 
     var commands = _dbContext.Shipments 
      .Where(x => x.OrderId == message.Id && x.Status != ShipmentStatus.Shipped) 
      .Select(x => new CancelShipment { 
       Id = x.Id 
      }); 

     _bus.Send(commands); 
    } 
} 

public CancelShipmentHandler : IHandleMessages<CancelShipment> 
{ 
    private DbContext _dbContext; 

    public void Handle(CancelShipmentHandler message) 
    { 
     // Similar to CancelOrder, only with shipments. 
    } 
} 

回答

3

這裏的答案取決於業務需求 - 例如,如果我們無法消除的出貨量之一,這是否意味着我們應該回退取消命令?

我的感覺是答案可能不是。因此,您使用的消息驅動模型似乎比在單個處理程序中同步所有內容更合適。

我的代碼有一個小問題,就是你在OrderCancelledHandler中發佈命令。你可能應該Bus.Send他們。

此外,通過執行一個Bus.Publish/Bus.Send,您表示處理完整的一組命令應該是一個事務。我不認爲你想要那樣。相反,我建議循環使用命令並分別爲每個命令做一個Bus.Send。

+0

事件處理程序中的Bus.Send是一個錯字,現在已更正。此外,謝謝澄清交易範圍。我還假設命令處理程序 - >事件處理程序 - >命令處理程序的流程在此處適用,因爲您只提出了一個問題。非常感謝反饋,Udi。 –

+1

這也隱含地回答了我的一個大問題,那就是NSB總是將事務每個消息的有效載荷(即通過一次調用傳遞給Bus.Send/Publish)進行範圍。 –