nodejs和sql查询 - 并发访问

时间:2014-01-08 18:04:01

标签: mysql node.js asynchronous concurrency

我正在发现nodejs及其异步系统,我正在使用node-mysql包在MySQL中进行查询。我正在做那样的事情:

  • 迭代集合
  • 如果该项目不在数据库中,我会插入
  • 如果该项目在数据库中,我会更新

所以我的代码看起来像那样:

var stuff = ['a', 'b', 'a'];
for(var i=0;i<stuff.length;i++){
    connection.query("SELECT COUNT(*) AS count FROM table WHERE column = ?", [stuff[i]],
    (function(err, rows){
        if(rows.count == 0){
            connection.query("INSERT INTO table ...");
        } else {
            connection.query("UPDATE table SET ...");
        }
    }).bind(this)
}

但我想知道,因为异步模式,如果有时这个模式有问题。这里的行为是什么?

  • “SELECT WHERE column ='a'”==&gt; count == 0
  • “SELECT WHERE column ='b'”==&gt; count == 0
  • “SELECT WHERE column ='a'”==&gt; count == 0
  • “INSERT'a'”
  • “INSERT'b'”
  • INSERT 'a'”==&gt;意外行为

  • “SELECT WHERE column ='a'”==&gt; count == 0
  • “INSERT'a'”
  • “SELECT WHERE column ='b'”==&gt; count == 0
  • “INSERT'b'”
  • “SELECT WHERE column ='a'”==&gt; count == 1
  • 更新'a'”==&gt;预期的行为!!

我希望你能理解我的问题,抱歉我的英语不好,这是一个真正的障碍......

谢谢。

2 个答案:

答案 0 :(得分:0)

mysql有一个插入或更新命令http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html如果它不存在则会插入,如果不存在则会更新。

对于使用此异步行为进行插入/更新,请查看async lib以串行运行此类内容。使用上面的代码示例,您无法确定哪个将运行/完成第一个IIRC。

这还取决于您要更新的具体内容。如果你只是计算一些东西,并且需要递增计数,那么顺序并不重要。同样,这一切都取决于您实际想要插入/更新的内容。

答案 1 :(得分:0)

我发现递归通常适用于这种挑战。我一直都在使用它 - 这似乎比诉诸async这样一个直截了当的问题更简单。

这样的事情:

var stuff = ['a', 'b', 'a'];

processStuff(stuff);

function processStuff(theStuff) {

    if (theStuff.length) == 0 {
        // Done all items - either return result to client or execute some callback here
        // res.end('Completed');
        return;
    }

    var thisItem = theStuff.shift();

    connection.query('SELECT * FROM table WHERE column = ' + connection.escape(thisItem), function(err, rows) {
        if (rows.length == 0) {
            connection.query("INSERT INTO table ...", function(err, result) {
                processStuff(theStuff);
            });
        } else {
            connection.query("UPDATE table SET ...", function(err, result) {
                processStuff(theStuff);
            });
        }
    });
}

这将使您的查询和更新/插入一个接一个地流动,但它仍然是异步的。我发现这也更容易阅读,并且易于修改。