繁体   English   中英

如何使用事务/原子进行多个REST请求?

[英]How to make multiple REST requests transactional/atomic?

我有以下情况。
我有一个REST客户端,作为其他3个REST客户端的外观。 (我用Java编程,使用Spring Boot)

客户的责任之一包括对用户进行CRUD操作。
现在,暴露自己的REST API的所有其他3个系统都有某种用户管理。

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

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

但是,请考虑用户创建仅在1个外部服务上成功的情况。 我是否会重试所有其他操作? 我是否尝试删除用户已被取代的用户?

这样做的正确方法是什么?

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

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

  1. 假设您的外观具有传入的CRUD请求的持久队列。 一旦新请求req进入队列,您就开始要求REST客户端执行它;
  2. 一旦所有REST客户端执行请求并报告成功,您就可以将其从队列中删除,并使此更改对系统的全局状态有效。 例如,如果req是CREATE,那么新用户对外部世界是可见的,如果req是更新,那么更新对外部世界是可见的,依此类推。 这意味着全局状态是门面系统数据库中存储的内容;
  3. 现在,如果在req正在进行时你的外观出现故障怎么办(并非所有REST客户端都报告成功)? 重新启动后,您的外观必须从(持久)队列中获取所有挂起的请求,并将它们推送到REST客户端。 这意味着REST客户端可以检测它们是否已经处理了该特定请求(并且它刚刚发生,Facade在它关闭之前没有处理回复)。 通常,这是通过使用唯一请求ID(例如,UUID)来实现的。

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

您需要根据具体情况处理它。 在您提供的示例中,您可以尝试删除,但这也可能会失败。

一旦出现故障,您需要:

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

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

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

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

启动请求的网页会返回错误。 用户重试。 这次你更新第一个并重试创建第二个和第三个。

对于客户查找记录,并获得部分用户,你要么需要跟踪哪些创建,或者客户自己将只需要看到1三所创建记录的第4个系统。 如果您的客户总是只是一次只看三个中的一个,这甚至可能不是问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM