当前位置: 首页 > 知识库问答 >
问题:

如何使多个REST请求事务性/原子性?

干高歌
2023-03-14

我有以下情况
我有一个REST客户端,它充当其他3个REST客户端的门面。(我正在用Java编程,使用Spring Boot)

客户机的职责之一包括对用户执行CRUD操作
现在,所有其他3个公开自己REST API的系统都有某种用户管理功能。

例如,当我收到创建用户的请求时,我必须通过REST API在这3个系统上创建它们,并将它们保存在我的数据库中。

现在,在最好的情况下,我只是调用他们的API,将用户插入我的数据库,一切都很好。

但是,请考虑这样的场景,即仅在一个外部服务上成功创建用户。是否在所有其他服务器上重试该操作?我是否尝试删除成功删除的用户?

正确的方法是什么?

共有3个答案

党源
2023-03-14

您需要逐案处理它。在您提供的示例中,您可以尝试删除,但这也可能失败。

一旦出现故障,您需要:

  1. 处理创建用户的重试
  2. 处理可能访问用户的客户端,即使只创建了3个客户端中的1个

对于重试,您可以让启动器重试或将请求排队。

在这两种情况下,您可能都希望设计api,以便在尝试重新创建已创建的用户时,它会将其视为更新。

例如,三个中只有一个成功。

发起请求的网页返回错误。用户重试。这次您更新第一个并重试创建第二个和第三个。

对于查找记录并获得部分用户的客户端,您要么需要第四个记录系统来跟踪创建的记录,要么客户端自己需要看到三个记录中只有一个被创建。如果你的客户总是一次只看三个选项中的一个,这甚至可能不是问题。

赏新知
2023-03-14

一种方法(假设您可以容忍节点之间的不同状态):

  1. 比方说,您的facade具有传入CRUD请求的持久队列。一旦队列中有新的请求,您就开始要求REST客户端执行它
  2. 一旦所有REST客户端执行了请求并报告成功,您就可以将其从队列中删除,并使此更改对系统的全局状态有效。E、 例如,如果创建了新用户,则外部世界可以看到新用户;如果更新了新用户,则外部世界可以看到更新,依此类推。这意味着全局状态存储在门面系统的数据库中
  3. 现在,如果您的facade在req进行过程中发生故障(并非所有REST客户端都报告成功),该怎么办?重新启动后,您的facade必须从(持久)队列中获取所有挂起的请求,并将它们推送到REST客户端。这意味着REST客户机可以检测到他们是否已经处理了那个特定的请求(事实上,facade在应答失败之前并没有处理)。通常,这是通过使用唯一的请求id(例如UUID)来实现的

如果您的系统只由部分REST客户端处理请求是安全的(这意味着外部世界只能通过facade访问数据),则上述过程可以工作。如果没有,您需要一些支持分布式事务的系统(google用于两阶段提交)。

邵宏达
2023-03-14

要做到这一点并不容易。如果您的“事务”的任何部分失败,您就无法可靠地回滚或重试以保证所有系统的一致性。您需要与所有三个(四个系统)紧密集成才能使用分布式事务系统。

 类似资料:
  • 在MongoDB中,写操作的原子性是在document级别上的,即使修改的是文档中的内嵌部分,写锁的级别也是document上。 当一个写操作要修改多个文档,每个文档的修改是原子性的。整个的写操作并不是原子性的,它可能和其他写操作产生交织。然而你可以使用$isolated隔离操作符来限制写操作,让它不与其他写操作交织。 不隔离性能更高,但是会产生数据的不确定性,隔离写操作,事务性更好。MongoD

  • 我正在评估Apache Kafka Streams的事件源,看看它在复杂场景中的可行性。与关系数据库一样,我也遇到过一些情况,原子性/事务性至关重要: 具有两项服务的购物应用程序: OrderService:有一个带有订单的Kafka流商店(OrdersStore) ProductService:有一家Kafka流商店(ProductStockStore),里面有产品及其库存 流量: > Orde

  • 我尝试使用在集成测试套件中测试。 ()调用注入的(),后者使用调用另一个REST服务器。这导致运行测试时出现以下错误。 resourceAccessException:获取“http://test123.com/42/status”的请求时出现I/O错误:test123.com;嵌套异常为java.net.UnknownHostException:test123.com 我使用对本身进行集成测试,

  • 我正在使用JSF 2.1Hibernate4.1.7Spring3.2.1Spring安全SQLServer2012的Web应用程序工作。一切正常,即CRUD操作。但有些方法需要处理 2 个或更多实体(更新、添加等),例如 如果在执行第2行(创建实体)时出现错误,我需要合并的实体(或更新、创建)或之前的DB函数来获得回滚,以便我的DB上的数据保持正确 我将与Spring注释结合使用。 在我的< c

  • 我有两个终点 http://localhost:8080/account/v1/credit/{帐号}(POST- 以及我的交易: 基本上,当调用信贷时,dto的金额将添加到与给定帐号相关的帐户余额中,到目前为止没有问题。 然而,当调用借记卡时,正如您在下面看到的,有多种取款交易类型(并且随着应用程序变大,可以添加更多的取款交易类型),例如BillPaymentTransaction、取款交易。

  • 我在JUnit中使用Mockito,并且我有一个使用RestTemboard向微服务发出请求的方法。 此方法返回一个JSON对象,该对象将在TokenRequestorPayload类中反序列化。 当我执行单元测试时,它们会失败,因为mock不起作用,我得到了一个org.springframework.web.client.ResourceAccessExcure。我怎么能嘲笑我的RestTem板