Nservicebus 有条件地开始传奇
我有两种类型的活动:Nservicebus 有条件地开始传奇,nservicebus,saga,Nservicebus,Saga,我有两种类型的活动: 人事变动 PersonalAddressChanged 当一个新的人(和一个新的地址)被创建(创建或更新)时,它们也会被发布 创建一个新人时,会发布两个事件:PersonChanged和PersonalAddressChanged(按顺序)。但是,由于NServiceBus是异步的,因此可以按任何顺序处理它们。当一个地址被改变时(对于一个现有的人),没有PersonChanged事件,只有PersonalAddressChanged事件 我想为PersonalAddre
- 人事变动
- PersonalAddressChanged
NServiceBus
是异步的,因此可以按任何顺序处理它们。当一个地址被改变时(对于一个现有的人),没有PersonChanged事件,只有PersonalAddressChanged事件
我想为PersonalAddressChanged事件编写一个处理程序,它将:
personchange→ PersonalAddressChanged
,因为有时任何特定的地址更改都不会发生PersonChanged事件。您可以通过sagas实现这一点,是的,尽管您可能不应该这样做。首先,在创建和更新人员时使用相同的事件会丢失事件中的语义信息(您正试图通过检查数据库中的用户来重新创建语义信息)。你还将自己暴露在许多潜在的比赛条件下,需要考虑如何应对这些条件。我的建议是修改您的消息流,这可能会消除您当前的问题
但是,如果您想尝试它,您可以这样做:(没有测试或编译,只是概念代码)
公共类MySaga:Saga,IAmStartedByMessage,IAmStartedByMessage{
公共覆盖无效配置HowtoFindsaga(){
//如何关联PersonChanged和PersonalAddressChanged消息
}
公共无效句柄(PersonChanged消息){
插入(味精);
if(Data.PendingAddressChange!=null)
更新数据库(msg);
MarkAsComplete();
}
公共无效句柄(PersonalAddressChanged消息){
if(信息数据库(信息人)){
更新数据库(msg);
MarkAsComplete();
}
否则{
Data.PendingAddressChange=msg;
}
}
}
公共类MySagaDataType:IContainSagaData{
PublicPersonalAddressChanged PendingAddressChange{get;set;}
}
我同意@carlpett关于重新思考活动的一些语义的说法
我也建议你在这里考虑一个不同的解决方案。
如果你的PersonalAddressChanged消息处理程序看到数据库中没有当前的人,就用它得到的地址创建一个呢?如果
PersonalAddressChanged
事件只针对一个现有的人发送,我根本不会为sagas操心
相反,我会依赖重试逻辑来处理无序到达的消息
无论何时处理PersonalAddressChanged
,它都可以假定存在个人记录。如果没有,则处理程序抛出异常,稍后重试
当它再次被加工时,
PersonChanged
事件已被处理,一切正常。我喜欢此解决方案,但我遇到以下错误:NHibernate.event.Default.AbstractFlushingEventListener-无法将数据库状态与会话NHibernate.PropertyValueException同步:错误:为Namespace.PersonSaga.PendingAddressChanged-->System.IndexOutOfRangeException:此SqlParameterCollection的索引29无效,计数为29
。有什么想法吗?@bpiec:您的事件是作为接口还是具体类实现的?NServiceBus围绕接口生成代理类,这可能是NHibernate不喜欢的。尝试用该类的内容替换PersonalAddressChanged
属性(即如果类PersonalAddressChanged{public string Address{get;set;}public Guid PersonId{get;set;}
,则将这两个参数移到MySagaDataType
中并分别设置)我在我的Saga类中添加了几个属性,每个属性都包含相同名称的属性,NSB在SQL Server中生成了错误的表,因此无法持久保存Saga:(没关系,我会尝试找到一个解决办法,但答案是我一直在寻找的!事实上,我有单独的添加和更改事件,但我不能假设当更改地址时,我在数据库中已经有一个人…我无法创建一个新的人,它必须通过验证,并且需要一些字段。然后@chrisbednarski的答案就是我想要的建议。