node.js sqlite事务隔离

node.js sqlite事务隔离,node.js,sqlite,transactions,Node.js,Sqlite,Transactions,如何确保SQLite不会将来自多个并发node.js/Express HTTP请求的查询交错到单个事务中 我希望来自不同请求的DB查询在单独的事务中执行,彼此隔离,允许彼此独立地提交或回滚。给定node.js的单线程和单数据库连接?这似乎特别有问题 我已经浏览了几十个网页和文档,还没有找到任何关于如何或是否处理这种情况的清晰解释。例如,db.serialize的描述只说明一次将执行一个查询——它没有说明属于不同事务的查询的分离 感谢任何指点 我面临着完全相同的问题。我是这样解决的: 步骤1:确保

如何确保SQLite不会将来自多个并发node.js/Express HTTP请求的查询交错到单个事务中

我希望来自不同请求的DB查询在单独的事务中执行,彼此隔离,允许彼此独立地提交或回滚。给定node.js的单线程和单数据库连接?这似乎特别有问题

我已经浏览了几十个网页和文档,还没有找到任何关于如何或是否处理这种情况的清晰解释。例如,db.serialize的描述只说明一次将执行一个查询——它没有说明属于不同事务的查询的分离


感谢任何指点

我面临着完全相同的问题。我是这样解决的:

步骤1:确保通过一组库函数完成所有数据库访问,其中数据库作为第一个输入参数传入

步骤2:使用新的sqlite3.database“path”创建数据库对象时,请使用一些额外的元信息包装该对象:

以下是我如何包装我的:

var wrap = { db_obj : new sqlite3.Database('path'), locked : "UNLOCKED", work_queue : [] }
步骤3:创建一个用于运行db函数的函数。如果数据库被锁定,此函数将推迟到稍后执行。我调用了我的runAsync:

function runAsync( db, fn, callBack) {
    if (db.locked === "LOCKED" ) {
        db.work_queue.push( function() { runAsync( db, fn, callBack ); });
        return;
    }
    fn(db,callBack);
}
我们可以看到,这个函数检查包装的db对象的状态。如果它被锁定,我们通过将函数存储在工作队列中来推迟执行,以便稍后通过执行fn来执行

步骤4:创建一个函数,该函数将用于以独占方式运行db函数。如果数据库被锁定,此函数将推迟到以后执行,否则它将锁定数据库,运行其函数,然后解锁数据库。我叫我的:runAsyncExclusive:

传递到函数中的exclusiveDb对象将允许以独占方式访问db。该对象本身可以被锁定,允许任意深度嵌套锁定

步骤5:调整库函数,使其在适当的情况下调用asyncRun和asyncRunExclusive:

function get(db,sql,params,callBack) {
    db.get(sql,params,callBack);
}
变成

function get(db,sql,params,callBack) {
    runAsync( db, function(db,cb) { db.get(sql,params,cb); }, callBack );
}


如果这不够清楚,请道歉

这是有道理的-谢谢!我认为您使用runAsync和runasynclusive这对函数来实现诸如多个读卡器和单个写卡器之类的模式似乎不是线程安全的。db.locked的读写操作不是以原子方式完成的。如果两个线程同时调用runAsyncExclusive怎么办?你可能会有两个线程读取db.locked===UNLOCKED并开始他们的业务。你是对的,这不是线程安全的。这不应该是个问题,因为node.js是单线程的,对吗?
function get(db,sql,params,callBack) {
    runAsync( db, function(db,cb) { db.get(sql,params,cb); }, callBack );
}