node.js - 使用 Node.js 防止竞争条件

标签 node.js queue amazon-dynamodb race-condition

我正在使用 nodeJS 6.3.0 和 aws DynamoDB 编写应用程序。

dynamodb 保存添加到 dynamodb 的统计信息,这些信息是从 10 个不同的函数(10 个不同的统计度量)调用的。间隔设置为 10 秒,这意味着每 10 秒,对我的函数进行 10 次调用以添加所有相关信息。

putItem 函数:

function putItem(tableName,itemData,callback) {
var params = {
    TableName: tableName,
    Item: itemData
};
docClient.put(params, function(err, data) {
    if (err) {
        logger.error(params,"putItem failed in dynamodb");
        callback(err,null);
    } else {
        callback(null,data);
    }
});

现在...我创建了一个队列。

var queue = require('./dynamoDbQueue').queue;

它实现了一个具有固定大小的简单队列,我从 http://www.bennadel.com/blog/2308-creating-a-fixed-length-queue-in-javascript-using-arrays.htm 获取该队列。 .

这个想法是,如果出现网络问题……让我们先说一分钟。我希望所有事件都被推送到队列,当问题解决时将队列信息发送到 dynamodb 并释放队列。

所以我将原来的函数修改为以下代码:

function putItem(tableName,itemData,callback) {
var params = {
    TableName: tableName,
    Item: itemData
};
if (queue.length>0) {
    queue.push(params);
    callback(null,null);
} else {
    docClient.put(params, function (err, data) {
        if (err) {
            queue.push(params);
            logger.error(params, "putItem failed in dynamodb");
            handleErroredQueue(); // imaginary function that i need to implement
            callback(err, null);
        } else {
            callback(null, data);
        }
    });
}
}

但是由于我有 10 个插入函数在同一秒运行,因此有可能出现竞争条件。这意味着...

execute1 - 一个函数验证队列为空...并且即将执行 docClient.put() 函数。

execute2 - 同时从 docClient.put() 返回的另一个函数出现错误,因此它将第一行添加到队列中。

execute1 - 当第一个函数调用 docClient.put() 时,问题已解决,并成功将数据插入到 dynamodb,这会在队列中留下将要释放的先前数据在下一次迭代中。

例如,如果我插入 4 行 ID 为 1,2,3,4,则插入到 dynamodb 的行的顺序为 1,2,4,3

有办法解决吗?

谢谢!

最佳答案

我认为您的方向是正确的,但我建议不要先检查错误然后将其添加到队列中,而是先将每个操作添加到队列中,然后每次从队列中读取数据。

例如,在您的情况下,您调用函数 1,2,3,4,它会产生 1,2,4,3,因为您在错误/中断操作期间使用队列。

Step1: All your function will make an entry to a Queue -> 1,2,3,4
Step2: Read your queue and make an insert, if success remove the element
       else redo the operation. This way it will insert in the desired sequence

另一个优点是,因为您使用队列,所以不必为表保持非常高的吞吐量。

编辑:

我想您只需要确保在完成第一个操作后您将执行下一个过程,而不是在此之前。

例如:fn 1 -> 从队列中读取(不要立即从队列中删除) -> 如果不再执行则操作完成 -> 从队列中删除 -> 执行下一个操作。

您只需确保从队列中读取并等待,直到收到 DynamoDB 的响应。

希望这有帮助。

关于node.js - 使用 Node.js 防止竞争条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38421574/

相关文章:

php - 在 Linux 上通过 .php 中的 .sh 运行 Node 文件

javascript - Hapijs - 向所有请求添加 cookie

javascript - Mongoose — 使用聚合创建带有 $sum 的新属性

queue - 如何清除NiFi队列?

amazon-web-services - S3 存储 JSON 与 DynamoDB

node.js - Fluxible 中的“脱水”和“再水合”代表什么?

c++ - 将项目添加到队列

c - 如何在树的最后一层(即堆(几乎完整的树))上找到最后一个(最右边的)节点?

amazon-dynamodb - 如何使用无服务器框架为多个环境配置 DynamoDB ProvisionedThroughput

amazon-dynamodb - 如何修复从 MS Edge 浏览器访问 DynamoDB 时出现的 CRC32 错误