3

我正在开发一个 DynamoDB用作数据库的项目,应用程序的每个用例都由message在数据库中创建/更新项目后的发布触发。目前代码遵循这种方法:

repository.save(entity);
messagePublisher.publish(event);

Udi Dahan 有一个视频Reliable Messaging Without Distributed Transactions,他在视频中谈到了系统在保存到 DB 后但在发布消息之前可能会立即失败的情况的解决方案,因为消息不是事务的一部分。但是在他的解决方案中,我认为他假设使用SQL数据库作为过程涉及保存,作为事务的一部分,正在处理的消息的correlationId,实体修改和要发布的消息。使用NoSQL数据库我想不出一种干净的方式来存储有关消息的信息。

一种解决方案是使用DynamoDB streams并订阅使用一个Lambda或另一个服务发布的事件,以将它们转换为特定于域的事件。我的问题是我无法从域逻辑发送消息,逻辑将分布在处理消息的服务和Lambda/service对更改的反应中,并且解决方案将是特定于平台的。

有没有其他方法来处理这个?

4

1 回答 1

2

我不能说基于 DynamoDB 的具体解决方案,因为我从来没有使用过这个引擎。但是我已经在 MongoDB 之上构建了一个事件驱动系统,因此我可以分享我的学习成果,您可能会发现对您的案例有用。

你可以有不同的方法:

1) 基于事件溯源方法,您可以只保存您的用例在事务中产生的事件/消息。在 Mongo 中,当您只是将新项目插入/附加到同一个集合中时,您可以确保原子性。无论如何,如果引擎不提供该功能,则查询操作是如此集中,以至于您至少可以减少出错的可能性。

一旦存储了所有事件,您就可以使用它们并将它们投影到给定状态,然后将更新的状态保存在另一个事务中。

在这里,您必须处理最终的一致性,因为在您预测事件之前,您的读取模型中的数据将是陈旧的。

2) 另一种方法是应用UnitOfWork缓存所有查询操作(插入/更新/删除)的模式来保存事件和状态。用例完成后,您将对数据库执行所有缓存查询(刷新)。这样,虽然操作不是原子的,但您再次将它们集中到足以最大限度地减少错误。

当然,如果您需要该功能,最好使用 ACID 数据库,并且任何其他方法都是接近它的解决方法。

关于发布事件,我不知道您的意思是不是将它们发布到消息传输机制,例如 rabbitmq、Kafka 等。但这必须是一个后台进程,您从数据库中获取事件并发布它们以中断同一事务中的 2 阶段提交。

于 2018-03-09T00:32:41.680 回答