【发布时间】:2013-10-16 19:41:00
【问题描述】:
我正在使用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
);
你也可以运行the full example。
问题是在begin 或insert 之后的异步暂停期间可以启动带有insert 或update 查询的其他代码。然后这个额外的查询在事务中运行。提交事务时,这不是问题。但是,如果事务被回滚,那么这个额外查询所做的更改也会被回滚。哎呀,我们只是意外丢失了数据,没有任何错误消息。
我考虑过这个问题,我认为一种解决方案是创建一个包装类,以确保:
- 同时只有一个事务在运行。
- 事务运行时,仅执行属于该事务的查询。
- 所有额外的查询都在当前事务完成后排队执行。
- 当一个事务已经在运行时,所有启动事务的尝试也将排队。
但这听起来太复杂了。有更好的方法吗?你如何处理这个问题?
【问题讨论】:
标签: node.js asynchronous sqlite transactions