neo4j 如何实现同步事务系统?

p4tfgftt  于 2022-11-05  发布在  其他
关注(0)|答案(3)|浏览(188)

让我们想象一下,我们在某个.NET Core * 控制器 * 中有一个名为CreateEntity的简单端点,我们有两个服务将 * 实体 * 保存到MongoNeo4j数据库(按此特定顺序)。
我想实现一些模式来确保我们拥有 * 一致 * 数据。
为什么?
因为我们可能会遇到这样的情况,当实体被添加到Mongo,但是对Neo4j的调用崩溃了,这意味着数据仍然插入在Mongo中。
一种解决方案是对第二次服务调用使用try-catch语句,对Mongo插入使用补偿事务。在这种情况下,从Mongo中删除实体。另一种解决方案是使用实体的状态,将Pending作为初始状态,并在成功进行Neo4j调用后将其标记为Completed
我还查看了Saga2PC模式,但它们用于异步上下文和跨微服务(您知道,通过使用RabbitMQ、Kafka、Service Bus等在微服务之间进行通信)
但在我的情况下,有一个单一的微服务。对此有什么想法?

fdx2calv

fdx2calv1#

您希望将mongo操作 Package 在一个transaction中,如果Neo4j失败,则回滚mongo事务,如果成功,则提交它。

fcg9iug3

fcg9iug32#

Temporal开源项目可用于在同步场景中实现补偿和SAGA。Temporal的基本思想是,当执行远程调用的代码出现故障时,您可以编写代码。如果进程出现故障,Temporal会将执行迁移到另一台机器上,其状态与崩溃前完全相同。该状态包括所有局部变量和阻塞调用。下面是一个使用Temporal Java SDK的 Saga 示例:

public void bookTrip(String name) {
    // Configure SAGA to run compensation activities in parallel
    Saga.Options sagaOptions = new Saga.Options.Builder().setParallelCompensation(true).build();
    Saga saga = new Saga(sagaOptions);
    try {
      String carReservationID = activities.reserveCar(name);
      saga.addCompensation(activities::cancelCar, carReservationID, name);

      String hotelReservationID = activities.bookHotel(name);
      saga.addCompensation(activities::cancelHotel, hotelReservationID, name);

      String flightReservationID = activities.bookFlight(name);
      saga.addCompensation(activities::cancelFlight, flightReservationID, name);
    } catch (ActivityFailure e) {
      saga.compensate();
      throw e;
    }
  }

遗憾的是,截至2022年夏天,.NET SDK for Temporal仍在开发中,目前支持的语言有Typescript/Javascript、Go、Java、Python和PHP。
对于.NET,您还可以使用基于与Temporal相同的思想的Durable Task Framework和/或Azure Durable Functions

yx2lnoni

yx2lnoni3#

某种形式的 Saga 在这里可能会很有用。有很多库,它们通常都有处理“补偿事务”的方法。
无论您是否选择预烘焙库,流程可能如下所示:

  • 在事务内将数据写入Mongo
  • 如果写入成功,则将消息发送到队列
  • 消息使用者负责写入Neo4j

如果最后一步失败了,发送一条消息到另一个队列。2它的消费者将负责从Mongo中删除数据。
我还建议使用Outbox模式来提高弹性。
(免责声明,我是OpenSligh的作者,这是一个.NET Saga 库)

相关问题