处理存储在 Datomic 中的无序消息?

Dealing with out-of-order messages stored in Datomic?

背景

在分布式系统中,消息可能以无序方式到达。例如,如果消息 A 在时间 T1 发送,消息 B 在时间 T2 发送,则有可能 B 在 A 之前收到。例如,如果 A 是一条消息,例如 "CustomerRegistered" 而 B 是 "CustomerUnregistered".

在其他数据库中,如果收到数据库中不存在的客户的 CustomerUnregistered,我通常会写一个墓碑。然后我可以在收到 CustomerRegistered 消息时检查此墓碑是否存在(并且可能根据用例简单地忽略此消息)。我当然也可以用 Datomic 做类似的事情,但我希望 Datomic 可以帮助我,这样我就不需要这样做了。

我想到的一个可能的解决方案是:

您是否可以撤回一个不存在的客户实体 (CustomerUnregistered),稍后当收到 CustomerRegistered 时,客户实体会在撤回 之前写入历史记录?如果可以将 :db/txInstant 设置为消息中定义的时间戳,那就太好了(我认为)。

问题

如何以一种惯用的方式处理 Datomic 中的这种情况?

作为一般原则,不要让您的应用程序代码操纵 :db/txInstant:db/txInstant 表示您了解 一个事实的时间,而不是它发生的时间。

也许您应该将取消注册视为添加关于客户的 Datom(例如通过即时类型的 :customer/unregistered 属性)而不是收回该客户的 Datom(这意味着:"forget that this customer existed" ).

但是,如果收回客户数据确实是您想要做的事情,我会使用一个记录来阻止客户注册交易发生(我会通过交易功能强制执行)。