web-dev-qa-db-ja.com

「node-sqlite3」で「db.serialize」はどのように機能しますか

最近、nodeと node-sqlite を使用してsqlite3を操作することを学んでいます。これがサンプルです。

var sqlite3 = require('sqlite3');
var db = new sqlite3.Database(':memory:');
db.serialize(function() {
    db.run("CREATE TABLE test(info TEXT)");
    db.run("INSERT INTO test (info) VALUES ('info1')");
})
db.close();

ドキュメントでは、db.serializedを使用してSQL行が順番に実行されるようになっていると述べましたが、db.serializeなしで順番に実行されないので、イベントから引き出されて混乱しましたキューに入れて順番に実行しますか?ここでどのように機能しますか?

実行するsqlが1つしかない場合、次のようにdb.serializeなしで実行しても安全ですか?

var sqlite3 = require('sqlite3');
var db = new sqlite3.Database(':memory:');
db.run("CREATE TABLE test(info TEXT)");
db.close();
17
Searene

serialize()関数内の各コマンドは、次のコマンドが開始する前にfinishで実行されることが保証されています。

あなたの例では、INSERTが実行される前に_CREATE TABLE_が終了します。 serialize()を使用しなかった場合、_CREATE TABLE_およびINSERTステートメントが並行して実行されます。これらは次から次へと急速に開始するため、テーブルが作成される前にINSERTが実際に終了し、存在しないテーブルにデータを挿入しようとするとエラーが発生します。

これは、競合条件と呼ばれます。プログラムを実行するたびに異なる勝者が得られる可能性があるためです。 _CREATE TABLE_がレースに勝った場合、プログラムは正常に動作します。しかし、INSERTがレースに勝った場合、プログラムはエラーで中断します。誰がレースに勝つかを制御できないので、serialize()は_CREATE TABLE_が最後に達するまでINSERTが開始するのを止め、毎回同じ結果を得るようにします。

ステートメントが1つだけの2番目の例では、serialize()が引き続き必要です。これは、run()がSQLクエリを開始しますが、すぐに戻るであり、クエリをバックグラウンドで実行するためです。次のコマンドはデータベースに対するclose()であるため、クエリの実行中にそれを切断します。

serialize()は内部クエリの最後が完了するまで返されないため、これを使用すると、クエリが完了するまでclose()が保留されます。

別の種類のクエリを使用している場合(たとえば、ユーザーがWebページのボタンをクリックしたときに、呼び出し間でデータベースが開いたままになっている場合)、おそらくserialize()は必要ありません。各クエリに続くコードが、クエリが完了する前にクエリを完了する必要があるかどうかによって異なります。

serialize()を使用するかどうかを決定するとき、非シリアル化されたクエリをコメントアウトされているように考え、コードが引き続き機能するかどうかを確認すると役立ちます。上記の最初の例では、_CREATE TABLE_コマンドを削除すると、次のINSERTステートメントが壊れます(挿入するテーブルがないため)。したがって、これらをシリアル化する必要があります。ただし、2つの_CREATE TABLE_コマンドがある場合、一方を削除しても他方には影響しないため、これらの2つのコマンドをシリアル化する必要はありません。

(このヒントはclose()には適用されません-ただし、すべての実行が終了したらclose()を呼び出すだけです。)

22
Malvineous

これは SQLiteドキュメント で見つけました。

database#closeメソッドは常に排他モードで実行されます。つまり、すべての以前のクエリが完了するまで待機し、クローズが保留されている間、node-sqlite3は他のクエリを実行しません。

最終的な質問に対する答えはyesのようです。実行するクエリが1つしかない場合、serialize関数は必要ありません。クエリが終了する前にデータベースが閉じられることを心配する必要はありません。SQLiteはそれをしないほど賢いからです! :)

1
Celeste Bancos