我正在尝试使用 Postgres 作为数据库在 Sails 0.10.5 中实现事务,但操作在最后没有提交(或回滚)。
这是我写下来的一个简单的事务场景作为测试(使用 async.js):
testTransaction: function(uri) {
var testFile = {
uri: uri,
details: { 'firstDetail': 'value' }
};
async.auto({
begin_transaction: function(callback) {
DataFile.query('BEGIN TRANSACTION;', callback);
},
new_data_file: ['begin_transaction', function(callback) {
DataFile.create(testFile).exec(callback);
}],
}, function(error, results) {
if (error) {
console.log(error.message);
DataFile.query('ROLLBACK;', function(e, r) {
return error.message;
});
return;
}
DataFile.query('COMMIT;', function(e, r) {
console.log("Saved file: " + results.new_data_file);
if (e) {
return "Error during commit";
}
return results.new_data_file;
});
});
}
然后,我运行该服务时没有错误;但是没有新的 DataFile enetity 添加到 Postgres 表中。如果我查看Postgres日志,我发现:
2014-12-04 10:35:01 GMT 7984 548038d0.1f30LOG: statement: BEGIN TRANSACTION;
2014-12-04 10:35:01 GMT 7977 548038d0.1f29LOG: execute <unnamed>: INSERT INTO "data_file" ("uri", "details", "created_at", "updated_at") values ($1, $2, $3, $4) RETURNING *
2014-12-04 10:35:01 GMT 7977 548038d0.1f29DETAIL: parameters: $1 = '/just/another/test/uri', $2 = '{"firstDetail":"value"}', $3 = '2014-12-04 10:35:01+00', $4 = '2014-12-04 10:35:01+00'
2014-12-04 10:35:01 GMT 7983 548038d0.1f2fLOG: statement: COMMIT;
2014-12-04 10:35:01 GMT 7983 548038d0.1f2fWARNING: there is no transaction in progress
所以我收到警告:"没有正在进行的交易"日志上的第三个元素是进程 ID。显然,COMMIT 语句是由与发出 BEGIN (7984) 的进程 (7984) 不同的进程发出的。这可能是问题所在吗?在处理 Sails 中的交易时,如何强制使用相同的流程?
事务依赖于使用同一连接进行的多个查询,但 Waterline 对每个查询使用不同的连接,这就是您收到"没有正在进行的事务"消息的原因 - 第二个查询使用不同的连接,该连接没有正在进行的事务。
除了将poolSize
设置为 1 之外,没有办法解决此问题(因此每个查询必须使用相同的连接)。
这是我们用于事务的库 - https://github.com/Shyp/pg-transactions。您将无法访问帮助程序方法 - .find()
,.update()
等,但至少这是可能的。