LoginSignup
14
5

More than 5 years have passed since last update.

Node.jsでsqlite3のserializeを使うときの注意点

Posted at

sqlite3のserialize

sqlite3の処理は通常callbackを使って完了したことを待つことができます。

db.run("INSERT INTO foo ...", (err) => {
  // 完了!
});

async/awaitを使っていい感じに書くと、こうでしょう。

async function run(sql) {
  return new Promise((resolve, reject) => {
    db.run(sql, (err) => {
      if (err) reject();
      else resolve();
    });
  });
}

await run("INSERT INTO foo ...");

しかし、serializeを使うと、何も考えずに同期的に書ける方法があります。便利!

db.serialize(() => {
  db.run("...");
  db.run("...");
  db.run("...");
});

注意点

残念ながら、同期的に書くことができるのはserialize内のコードだけで、それ以外は非同期で実行されてしまいます。
つまり、以下のようなコードは、非同期で同時に実行される可能性があります。
おそらく、いっこめのINSERTが終わったあたりでSELECT文が実行されてしまうでしょう。

db.serialize(() => {
  db.run("INSERT INTO FOO ...");
  db.run("INSERT INTO FOO ...");
  db.run("INSERT INTO FOO ...");
});
db.all("SELECT * FROM foo");

対策

serializeをいい感じにasync/awaitでラップしましょう。
最後の処理で、resolveしてあげます。

async function serialize() {
  new Promise(resolve => {
    db.serialize(() => {
      db.run("INSERT INTO FOO...");
      db.run("INSERT INTO FOO...");
      db.run("INSERT INTO FOO...");
      db.run("INSERT INTO FOO...", () => resolve());
    });
  });
}

以上です。よろしくお願いいたします。

14
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
5