在并发sqlite3写入期间性能下降

时间:2014-04-10 00:00:27

标签: javascript node.js performance error-handling sqlite

为基于云的API编写测试套件。我需要使用虚假用户数据为数据库建立种子 - 部分数据来自API服务器 - (在使用伪造的用户详细信息注册后,从API服务器接收API密钥和密钥)

当尝试使用带有节点的sqlite3将记录写入文件时,我尝试以一种天真的方式编写逻辑,没有任何错误检查 - 但它失败了许多SQLITE_BUSY数据库锁定错误。

然后我添加了代码以便在出现错误的情况下重试,但是不够 - 最终导致损坏的表格,所以我按照freenode上#node.js的建议添加了事务。

现在,它有效。然而问题是它很慢 - 大约50个记录需要5分钟。此外,我需要传入大约number_of_users * 2的重试参数,以便成功完成该过程,否则它将失败。有些事情是不正确的,但我不能把它钉死。 SQLite3的性能不能这么慢。

有什么问题?

TestController.prototype.connectToDb = function () {
    var db = new sqlite3.Database(this.dbpath);
    return db;
}

TestController.prototype.writeUserToLocalDatabase = function (retries,username,useremail,password,api_key,api_secret, callback_after_all_users_have_been_added) {
    var dbase = this.connectToDb();
    var controller = this;

    if (retries < 0) {
       console.log("Bailing out of writeUserToLocalDatabase after max retry attempts");
       return;
    }

    dbase.run("BEGIN TRANSACTION");
    //console.log("Try #"+retries);
    var stmt = dbase.prepare("insert into user_table values(?,?,?,?,?)", function(err) {
        if(err !== null) {
          console.log("Error when trying to write user to database in prepare! "+err);
          dbase.run("ROLLBACK");
          dbase.close(function(err){if(err !== null) {console.log("Close failed in in prepare "+err);}});
          controller.writeUserToLocalDatabase(--retries,username,useremail,password,api_key,api_secret, callback_after_all_users_have_been_added);
       }
    });

    stmt.run(username,useremail,password,api_key,api_secret, function(err) {
       if(err !== null) {
          //console.log("Error when trying to write user to database in run! "+err);
          stmt.finalize();
          dbase.run("ROLLBACK");
          dbase.close(function(err){if(err !== null) {console.log("Close failed in in run "+err);}});
          controller.writeUserToLocalDatabase(--retries,username,useremail,password,api_key,api_secret, callback_after_all_users_have_been_added);
       }
       else {
          stmt.finalize(function(err) {
             if(err !== null && err !== undefined) {
                console.log("Error when trying to write user to database in finalize ! "+err);
                dbase.run("ROLLBACK");
                dbase.close(function(err){if(err !== null) {console.log("Close failed in in finalize "+err);}});
                controller.writeUserToLocalDatabase(--retries,username,useremail,password,api_key,api_secret, callback_after_all_users_have_been_added);
             }
             else {
                dbase.run("COMMIT");
                controller.appendToUserFile(useremail,password,api_key,api_secret);
                controller.pending_db_writes_for_user--;
                if (controller.pending_db_writes_for_user <= 0) {
                   console.log("Finished writing all users, now invoking db.close with callback");
                   dbase.close(callback_after_all_users_have_been_added);
                }
                else {
                   console.log("Remaining users to add: "+controller.pending_db_writes_for_user);
                   dbase.close(function(err){if(err !== null) {console.log("Close failed in after adding user "+err);}});
                }
             }
          });
       }
    });
}

更新:我能获得理智表现的唯一方法是使用async.queue限制sqlite3写入,队列大小为1。

0 个答案:

没有答案