是javascript回调原子

时间:2019-02-04 03:15:59

标签: javascript node.js express

我想确保托管在不同位置的两个独立第三方数据库中的字段是同步的。我有以下通用节点/表达js代码:

router.post ('url', function(req,res,next) {

    third_party_api_1.set_a (req.body.param, function(err, a) {

        third_party_api_2.set_b (req.body.param, function(err, b) {
            res.end()
        })

    })

})

如果最终用户发帖(参数= 1),我希望(a = b = 1)。如果他们发布(参数= 2),我期望(a = b = 2)。如果两个用户同时发布(param = 1)和(param = 2),那么第三方数据库中的a和b总是相等吗?我知道根据时间的不同,它们可以是1或2,但是我想确保它是(a = b = 1)或(a = b = 2),而不是(a = 1,b = 2)或( a = 2,b = 1)。

换句话说,set_aset_b是“原子的”吗?

谢谢!

编辑#1: “ a”是第三方数据库中的单个值,“ b”是另一个第三方数据库中的另一个单值,我希望用户发布单个值,并且我的代码将a和b都替换为该用户值。

编辑#2: 我无法直接控制第三方数据库,只能调用公共api。也许我需要在api调用周围使用互斥锁?我该如何实施?

3 个答案:

答案 0 :(得分:3)

您似乎在问两个分布式系统之间的“一致性”,而不是原子性。

您要问的实际上是一个架构问题,而不是JavaScript特有的问题。如果要针对两个不同的数据存储区进行调用,则需要某种方式来确保这两个端点保持一致。

答案 1 :(得分:1)

遗憾的是,答案是否定的。即使您的代码看起来像下面的示例,也不是安全的,因为对setAsetB的调用可能与多个调用者交错。

router.post ('url', function(req,res,next) {
    api1.setA(req.body.param);
    api2.setB(req.body.param);
 });

您还必须考虑如果您的应用程序最终部署到一组负载平衡的Web服务器上会发生什么。

在不了解有关您实际上正在更新的数据库的情况下,很难推荐解决方案。它们是完全不透明的,还是服务位于某种关系/文档数据库的前面?

答案 2 :(得分:0)

问题在于数据库一致性,在这种情况下,您的体系结构将更负责维护分布式存储之间的一致性。

例如:考虑具有分片和复制部署的MongoDB,无论您的请求如何,存储在上次调用您的请求之后将更负责创建一致的数据。