2014-11-14 47 views
1

我在几个网页上抓取表并使用表中的项更新MYSQL数据库。我正在使用MYSQL模块,并在遍历所有行时遇到各种错误。下面是功能一次迭代:在nodejs中循环mysql查询

var connection = mysql.createConnection(opts); 
    connection.connect(); 

function updateDB(o,lang){ 
    var tbl_name = "news_"+lang; 
    o.forEach(function(entry,index,arr){ 
     var sql1 = "SELECT * FROM "+tbl_name+" WHERE url = '"+htmlencode.htmlEncode(entry.url)+"' and omit = '1'"; 
     connection.query(sql1, function(err, rows, fields) { 
     connection.end(); 
     if (err){ 
      console.log("can't run query=" + sql1 +"\n Error="+err); 
     } 
     else{ 
      console.log('ROWS:',rows); 
      // if rows.length = 0 then update table with new info here... 
     } 
     }); 
    }); 
}; 

,如果我注释掉connection.end()线,但随后的连接永远不会结束,处理保持永远活着的实际工作。我将它作为批处理脚本运行,因此我需要它以优雅的方式结束。随着connection.end()到位我得到一个"Cannot enqueue Quit after invoking quit."

我试图把connection.end在使用async.series的最终回调,但仍然无法正常工作。我已经尝试使用池和不同的代码迭代来尝试获得某些工作。我用我的智慧结束了使用mysql模块,并想知道是否有另一个更好的工作。

回答

0

看起来您只有一个连接,并且您使用的是不友好的异步.forEach

您应该使用连接池和async.eachLimit来控制并发性。

var pool = mysql.createPool({ 
    host: process.env.MYSQL_HOST, 
    user: process.env.MYSQL_USER, 
    password: process.env.MYSQL_PASS, 
    database: process.env.MYSQL_NAME, 
    connectionLimit: 10 
}); 

function updateDB(o,lang){ 
    // submit as a sub-function to get the `lang` closure 
    // this could probably be organized a different way, but this fits your structure 
    function submit(entry, callback) { 
    var tbl_name = "news_"+lang; 
    var sql = [ 
     'SELECT * FROM ' + tbl_name, 
     ' WHERE url="?" and omit="1"' 
    ].join(''); 
    pool.getConnection(function(err, connection) { 
     if(err) return callback(err); 
     connection.query(sql, [entry.url], function(err, results) { 
     connection.release(); 
     if(err) return callback(err); 
     console.log('ROWS:',results); 
     }); 
    }); 
    } 

    async.eachLimit(o, 10, submit, function(err) { 
    if(err) throw err; 
    console.log('Done processing'); 
    }); 
} 

即使您不需要多个连接,您也应该几乎总是使用一个池。池会根据需要重新创建连接。这很方便,因为你的连接可能会导致mysql超时,网络问题以及其他许多原因。当你使用一个池时,你的代码将更加健壮。

如果您只想一次执行一个查询,只需将第二个参数更改为async.eachLimit1

+0

谢谢,但我有同样的问题,连接永不结束,所以我从来没有得到“完成处理”控制台日志。 – septemberbrain 2014-11-14 21:30:27