交易风格的HTTP请求 [英] Transaction-Style HTTP requests

查看:64
本文介绍了交易风格的HTTP请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近遇到了这样的问题:

I recently ran into such problem:

对于每个用户,我需要在服务器端执行以下操作:

For each user, I need to do the following on server side:

First
(SQL)  Insert user's record with a Unique constraint on ID
Then Parallel
(Http) Subscribe user to Service A, get subscription_id_A
(Http) Subscribe user to Service B, get subscription_id_B
Finally
(SQL)  Update user's record with both subscription ids

理想情况下,我希望整个操作都是事务性的,例如,如果任何HTTP请求或sql失败,就好像什么都没有发生.补充:如果请求A失败但B成功,那么我会陷入困境:我是否取消交易并最终导致未跟踪的订阅,还是提交并最终导致用户缺少订阅

Ideally I want this entire operation to be transactional, eg if any of http requests or sql fails, it would be as if nothing happened. Added: if Request A fails but B succeeds, I would be stuck: Do I cancel the transaction and end up with an untracked subscription or do I commit it and end up with user missing a subcription

鉴于这可能是不可能实现的,那么我接下来能做的最好的事情是什么?

Given that this is likely impossible to achieve, what would be the next best thing I can do?

服务A和B确实提供了API,以检查订阅是否存在以及也可以修改,删除订阅,但是我想避免使用先检查后行"风格. SQL服务器具有最高的隔离级别

The service A and B does provide APIs to check for existence of subscriptions and to modify, delete a subscription too, but I want to avoid the Check Then Act style. The SQL server has highest isolation level

推荐答案

这确实是一个标准问题. (通常,开发人员不知道此问题,只能在生产中找到.)没有标准的解决方案.通常无法解决(请参见 http://en.wikipedia.org/wiki/Two_Generals %27_Problem -两个系统永远不能百分百地确定应该提交还是中止).

This is indeed a standard problem. (Often, developers are not aware of this problem and only find out in production.) There is no standard solution. It is impossible to solve in general (see the http://en.wikipedia.org/wiki/Two_Generals%27_Problem - two systems can never agree with 100% certainty on whether they should commit or abort).

也许您可以先执行所有SQL工作.插入用户但没有订阅ID.然后,您尝试一个接一个地添加订阅,并在获得它们后在单独的事务中添加它们的ID.

Maybe you can perform all the SQL work first. Insert the user but without subscription IDs. You then try to add the subscriptions one by one and add their IDs in separate transactions once you got them.

安装一个后台作业,该作业定期检查很久以前创建的但尚未订阅的用户.如果发现任何差异,请修复它们并记录下来.

Install a background job that periodically checks for users that have been created a long time ago but that do not have subscriptions yet. If you find any discrepancies fix them and log this fact.

此定期清理可确保临时故障(由于网络故障,超时,重新部署,错误等而导致的 )是临时的.如果愿意,还可以确保检测到它们并将其报告给开发人员.

This periodic cleanup ensures that temporary failures (which will occur due to network glitches, timeouts, redeployments, bugs, ...) are temporary. It also ensures that they are being detected and reported to developers if you like.

这将是一个最终一致的系统.这个想法是首先以事务方式记录目标状态(用户和创建两个订阅的目标),然后让后台工作尝试将数据收敛到目标状态.

This would be an eventually consistent system. The idea is to first transactionally record the target state (the user and the goal to create two subscriptions) and then have a background job try to converge the data to the target state.

这篇关于交易风格的HTTP请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆