Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/419.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 并发sqlite3写入期间性能下降_Javascript_Node.js_Performance_Error Handling_Sqlite - Fatal编程技术网

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

Javascript 并发sqlite3写入期间性能下降,javascript,node.js,performance,error-handling,sqlite,Javascript,Node.js,Performance,Error Handling,Sqlite,为基于云的API编写测试套件。我需要使用伪造的用户数据(部分数据来自API服务器)为数据库种子,在注册伪造的生成的用户详细信息后,从API服务器接收API密钥和机密 当尝试使用sqlite3 with node将记录写入文件时,我尝试以一种朴素的方式编写逻辑,没有任何错误检查,但由于大量SQLITE_BUSY数据库锁定错误而失败 然后,我添加了代码,以便在出现错误时重试,但代码不足-最终导致表损坏,因此我添加了freenode上node.js中建议的事务 现在,它起作用了。然而问题是它的速度太慢

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

当尝试使用sqlite3 with node将记录写入文件时,我尝试以一种朴素的方式编写逻辑,没有任何错误检查,但由于大量SQLITE_BUSY数据库锁定错误而失败

然后,我添加了代码,以便在出现错误时重试,但代码不足-最终导致表损坏,因此我添加了freenode上node.js中建议的事务

现在,它起作用了。然而问题是它的速度太慢了——大约50条记录需要5分钟。另外,我需要传入一个retries参数,该参数大约为\u 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);}});
                }
             }
          });
       }
    });
}

更新:获得正常性能的唯一方法是使用队列大小为1的async.queue限制sqlite3写入。

一个字:我明白了。。。谢谢,我会调查的。但是sqlite3模块的默认行为是令人费解的。update:我能获得一些正常性能的唯一方法是使用队列大小为1的async.queue来限制db写入。鉴于sqlite是一个文件,这并不奇怪。据我所知,sqlite3节点模块只提供sqlite3,而不是任何额外的复杂数据库管理,因此它仍然是一个单独的文件,您需要在其中串行写入数据,而不是并行写入数据。这也是为什么sqlite非常适合于原型设计和经常读/偶尔写的存储。如果需要并发写入,可以使用“真实”数据库。