如何实施同步交易系统?

发布于 2025-02-13 21:03:12 字数 754 浏览 2 评论 0原文

让我们映像我们在某些.net core controller 中有一个简单的端点,称为createNentity,我们有两个服务,可以保存 Entity /em>到mongoneo4j数据库(按照此特定顺序)。

我想实现一些模式,以确保我们拥有一致的数据。

为什么?

因为我们可能会有添加到mongo的情况时,但呼叫neo4j崩溃。这意味着数据仍然插入mongo

一种解决方案是使用try-catch语句进行第二个服务调用,并使用mongo插入的补偿事务。在这种情况下,从mongo中删除实体。另一个可能是将状态用于实体,并将未决作为初始状态,并将其标记为 neo4j成功进行了呼叫。

我还浏览了 saga 2pc 模式,但它们用于异步环境和跨微服务(您知道,通过与Rabbitmq,Kafka,Service Bus,Service Bus&amp& )

,但就我而言,有一个微服务。对此有什么想法吗?

Let's image that we have a simple endpoint called CreateEntity in some .NET Core controller and we have two services which saves the entity to the Mongo and Neo4j databases (in this particular order).

I want to implement some pattern to make sure that we have consistent data.

Why ?

Because we might have situations when entity is added to Mongo, but the call to the Neo4j crashes. And that means the data remains inserted in the Mongo.

One solution is to use try-catch statement for second service call and use compensating transactions for Mongo insert. In this case, remove the entity from Mongo. Another one could be using a state for entity and put Pending as initial state and mark it as Completed after Neo4j call is made with success.

I also looked over SAGA and 2PC patterns but they are used in asynchronous contexts and across microservices (you know, by communicating between microservices with RabbitMQ, Kafka, Service Bus & other)

But in my case there is a single microservice. Any ideas on this ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

冰火雁神 2025-02-20 21:03:12

您想在交易中。如果Neo4J失败,请返回Mongo交易,如果成功,请进行提交。

You want to wrap your mongo operations in a transaction. If the Neo4j fails, roll back the mongo transaction, if it succeeds, commit it.

瞳孔里扚悲伤 2025-02-20 21:03:12

时间开源项目可用于在同步场景中实现补偿和萨加斯。时间的基本思想是,您将代码写为执行远程调用的代码的故障,不可能发生。如果流程失败,时间将在与崩溃之前完全相同的状态中迁移执行到其他机器。该州包括所有本地变量和阻止调用。
这是使用临时java sdk的传奇示例:

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年夏天,正在开发。当前支持的语言是Typescript/JavaScript,GO,Java,Python & php。

对于.net,您还可以使用持久的任务框架和/或

Temporal open source project can be used to implement compensations and SAGAs in synchronous scenarios. The basic idea of Temporal is that you write your code as a failure of the code that performs remote calls cannot happen. In case of a process failure Temporal is going to migrate the execution to a different machine in exactly the same state as before the crash. The state includes all local variables and blocking calls.
Here is a SAGA example using Temporal Java SDK:

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;
    }
  }

Unfortunately, the .NET SDK for Temporal is still under development as of the summer of 2022. The currently supported languages are Typescript/Javascript, Go, Java, Python & PHP.

For .NET you can also use Durable Task Framework and/or Azure Durable Functions that are based on the same idea as Temporal.

つ低調成傷 2025-02-20 21:03:12

某种形式的传奇可能在这里很有用。周围有很多图书馆,它们通常都可以处理“补偿交易”。

预烘烤库

  • 是否要
  • 使用

不管 最后一步失败,将消息发送到其他队列。它的消费者将负责从Mongo中删除数据。

我还建议使用发件框图案提高弹性。

(免责声明,我是Opensleigh的作者,一个.NET SAGA库)

some form of Saga might be useful here. There's plenty of libraries around, and they usually all have a way to deal with "compensating transactions".

Regardless you go for a pre-baked library or not, the flow might be something like this:

  • write data to Mongo inside a transaction
  • if write is successful, send a message to a queue
  • the message consumer takes care of writing to Neo4j

in case the last step fails, send a message to a different queue. Its consumer will take care of removing data from Mongo.

I'd also suggest to use the Outbox pattern to improve the resiliency.

(disclaimer, I'm the author of OpenSleigh, a .NET Saga library)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文