私はnode-sqlite3を使用していますが、この問題は別のデータベース ライブラリでも発生すると確信しています。トランザクションと非同期コードが混在しているコードでバグを発見しました。
function insertData(arrayWithData, callback) {
// start a transaction
db.run("BEGIN", function() {
// do multiple inserts
slide.asyncMap(
arrayWithData,
function(cb) {
db.run("INSERT ...", cb);
},
function() {
// all done
db.run("COMMIT");
}
);
});
}
// some other insert
setInterval(
function() { db.run("INSERT ...", cb); },
100
);
完全な例を実行することもできます。
問題は、またはの後の非同期一時停止中に、insert
またはクエリを使用した他のコードをupdate
起動できることです。次に、この追加のクエリがトランザクションで実行されます。トランザクションがコミットされている場合、これは問題ではありません。ただし、トランザクションがロールバックされると、この余分なクエリによって行われた変更もロールバックされます。エラー メッセージが表示されずにデータが予期せず失われただけです。begin
insert
私はこの問題について考えました.1つの解決策は、次のことを確認するラッパークラスを作成することだと思います:
- 同時に実行されるトランザクションは 1 つだけです。
- トランザクションの実行中は、トランザクションに属するクエリのみが実行されます。
- 余分なクエリはすべてキューに入れられ、現在のトランザクションが終了した後に実行されます。
- トランザクションが既に実行されているときにトランザクションを開始しようとすると、すべてキューに入れられます。
しかし、それは複雑すぎるソリューションのように思えます。より良いアプローチはありますか?この問題にどう対処しますか?