sql - 事务式 HTTP 请求

标签 sql http transactions atomic

我最近遇到这样的问题:

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

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 成功,我会被卡住:我是取消交易并以未跟踪的订阅结束,还是提交它并以用户丢失订阅结束

鉴于这可能无法实现,我能做的下一个最好的事情是什么?

服务 A 和 B 确实提供 API 来检查订阅是否存在以及修改、删除订阅,但我想避免 Check Then Act 样式。 SQL Server 具有最高的隔离级别

最佳答案

这确实是一道标准题。 (通常,开发人员并没有意识到这个问题,只是在生产中才发现。)没有标准的解决方案。一般不可能解决(参见 http://en.wikipedia.org/wiki/Two_Generals%27_Problem - 两个系统永远无法 100% 确定它们应该提交还是中止)。

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

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

这种定期清理确保临时故障(由于网络故障、超时、重新部署、错误等而发生)是临时的。如果您愿意,它还可以确保它们被检测到并报告给开发人员。

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

关于sql - 事务式 HTTP 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28848628/

相关文章:

sql - 在 AREL 中分组 ands 和 ors

php - 查询输出php代码

mysql - 使用group by和join时无法获取每天的最后订单金额

java - Hive 事务正在崩溃

java - 在 @Transactional 方法之前创建的 Hibernate 对象不能在之后使用(获取 LazyInitializationException)

MySQL 查询从 1000 万行表中获取每个条目的最新记录

PHP,框架 - 类必须声明为抽象的

java - 如何使用 Ngrok 将简单的 Java HTTP 客户端应用程序连接到 Web 资源?

android - 即使有事务,SQLite 插入也会变慢

Tornado 未正确返回 HTTP 状态消息