我有一堆处于长期运行过程的各种状态的现有 sagas。
Saga.UniqueAttribute
最近,我们决定通过使用(更多关于这里http://docs.particular.net/nservicebus/nservicebus-sagas-and-concurrency)来使我们的 IContainSagaData 实现上的属性之一独一无二。
部署更改后,我们意识到没有找到所有旧的 saga 实例,并且在进一步挖掘(感谢 Charlie!)后发现,通过添加唯一属性,我们需要对 Raven 中的所有现有 saga 进行数据修复。
现在,这很糟糕,有点像在数据库列中添加索引,然后发现所有表数据不再可选择,但既然如此,我们决定创建一个工具来执行此操作。
因此,在创建并运行此工具之后,我们现在已经修补了旧的 sagas,使它们现在类似于新的 sagas(自从我们接受更改后创建的 sagas)。
然而,尽管所有数据现在看起来都正确,但我们仍然无法找到该传奇的旧实例!
我们编写的工具做了两件事。对于每个现有的 saga,该工具:
- 将一个名为“NServiceBus-UniqueValue”的新 RavenJToken 添加到 saga 元数据中,将值设置为与该 saga 的唯一属性相同的值,并且
- 创建一个 NServiceBus.Persistence.Raven.SagaPersister.SagaUniqueIdentity 类型的新文档,相应地设置 SagaId、SagaDocId 和 UniqueValue 字段。
我的问题是:
- 仅仅使数据看起来正确就足够了,还是我们需要做其他事情?
- 我们的另一个选择是还原添加了唯一属性的更改。但是,在这种情况下,自从更改发生以来创建的那些新 sagas 是否可以接受?
添加元数据令牌的代码:
var policyKey = RavenJToken.FromObject(saga.PolicyKey); // This is the unique field
sagaDataMetadata.Add("NServiceBus-UniqueValue", policyKey);
添加新文档的代码:
var policyKeySagaUniqueId = new SagaUniqueIdentity
{
Id = "Matlock.Renewals.RenewalSaga.RenewalSagaData/PolicyKey/" + Guid.NewGuid().ToString(),
SagaId = saga.Id,
UniqueValue = saga.PolicyKey,
SagaDocId = "RenewalSaga/" + saga.Id.ToString()
};
session.Store(policyKeySagaUniqueId);
非常感谢任何帮助。
编辑
感谢 David 在这方面的帮助,我们解决了我们的问题 - 关键区别在于我们使用SagaUniqueIdentity.FormatId()
来生成文档 ID 而不是新的 guid - 这是微不足道的,因为我们已经引用了 NServiceBus 和 NServiceBus.Core 程序集。