事务样式的HTTP请求

时间:2015-03-04 07:19:39

标签: 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服务器具有最高的隔离级别

1 个答案:

答案 0 :(得分:1)

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

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

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

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

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