![](/img/trans.png)
[英]Why do sagas (aka, process managers) contain an internal state and why are they persisted to the event store?
[英]What are sagas and why are they used event driven architectures?
我遇到以下代碼:
public class ShippingSaga : Saga<ShippingSagaData>,
ISagaStartedBy<OrderAccepted>,
ISagaStartedBy<CustomerBilledForOrder>
{
public void Handle(CustomerBilledForOrder message)
{
this.Data.CustomerHasBeenBilled = true;
this.Data.CustomerId = message.CustomerId;
this.Data.OrderId = message.OrderId;
this.CompleteIfPossible();
}
public void Handle(OrderAccepted message)
{
this.Data.ProductIdsInOrder = message.ProductIdsInOrder;
this.Data.CustomerId = message.CustomerId;
this.Data.OrderId = message.OrderId;
this.CompleteIfPossible();
}
private void CompleteIfPossible()
{
if (this.Data.ProductIdsInOrder != null && this.Data.CustomerHasBeenBilled)
{
this.Bus.Send<ShipOrderToCustomer>(
(m =>
{
m.CustomerId = this.Data.CustomerId;
m.OrderId = this.Data.OrderId;
m.ProductIdsInOrder = this.Data.ProductIdsInOrder;
}
));
this.MarkAsComplete();
}
}
}
從上面代碼中的事物看,sagas似乎是某種事件的高級協調器/控制器。 如果是這樣,它們僅在事件驅動的體系結構中使用嗎? 最后,基礎設施的sagas部分是嗎?
第一個查詢似乎已得到回答。 但是在責任方面,即基礎架構,它們真正屬於哪兒呢? 域? 。 這些僅適用於EDA嗎?
警告:存在一些混亂,尤其是在圍繞“ Saga”的定義的nservicebus周圍; 見下文。
從根本上講, 流程管理器是讀取模型-您從事件歷史記錄中重新混合它們,並向它們查詢應運行的命令列表。
它們類似於人類查看視圖並將命令發送到寫入模型的過程。 有關此觀點的更多信息 ,請參見Rinat Abdullin的文章《 不斷發展的業務流程 》。
它們充當業務流程的描述,也就是說,它們標識應由聚合運行的其他決策(命令)。 在實現中,它們是非常多的狀態機-給定事件X和事件Y,流程管理器處於狀態(XY),並且它建議的命令是固定的。
我發現如果將狀態機(純粹的邏輯)與副作用(與總線的交互作用)分開,會更容易想到它們。
public class ShippingSaga : Saga,
ISagaStartedBy<OrderAccepted>,
ISagaStartedBy<CustomerBilledForOrder>
{
public void Handle(CustomerBilledForOrder message)
{
this.process.apply(message);
this.CompleteIfPossible();
}
public void Handle(OrderAccepted message)
{
this.process.apply(message);
this.CompleteIfPossible();
}
private void CompleteIfPossible()
{
this.process.pendingCommands().each ( m=>
this.Bus.Send(m);
}
}
}
或等效地-如果您想考慮不變的數據結構
public class ShippingSaga : Saga,
ISagaStartedBy<OrderAccepted>,
ISagaStartedBy<CustomerBilledForOrder>
{
public void Handle(CustomerBilledForOrder message)
{
this.process = this.process.apply(message);
this.CompleteIfPossible();
}
public void Handle(OrderAccepted message)
{
this.process = this.process.apply(message);
this.CompleteIfPossible();
}
private void CompleteIfPossible()
{
this.process.pendingCommands().each ( m=>
this.Bus.Send(m);
}
}
}
因此,運輸過程是根據業務領域定義的,並且NServiceBus“ Saga”將業務領域中的某些部分與總線基礎結構進行接口。 分離關注點不是很好。
我在引號中使用“ Saga”,因為-NService總線sagas不是特別適合該術語的先前使用
術語saga通常在CQRS的討論中用來指代一段代碼,該代碼在有界上下文和聚合之間協調和路由消息。 但是,出於本指南的目的,我們更傾向於使用術語“過程管理器”來指代這種類型的代碼工件。 有兩個原因:
- 術語saga有一個眾所周知的定義,其含義與與CQRS有關的一般含義有所不同。
- 術語過程管理器是對這種類型的代碼工件執行的角色的更好描述。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.