问题
I am trying to implement a transaction in Sails 0.10.5 using Postgres as database, but the operations are not committed (or rolled back) at the end.
This is a simple transaction scenario I wrote down as a test (using 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;
});
});
}
Then I run the service without errors; but no new DataFile enetity is added to the Postgres table. If I check the Postgres log, I find out that:
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
So I get the warning: "there is no transaction in progress" The third element on the log is the Process ID. Apparently the COMMIT statement is issued by a different process (7983) than the one that issued the BEGIN (7984). Might this be the issue?. How can I force to use the same process when dealing with transactions in Sails?
回答1:
Transactions rely on several queries being made with the same connection, but Waterline uses a different connection for every query, which is why you're getting the "there is no transaction in progress" message - the second query is using a different connection, which doesn't have an in-progress transaction.
There's no way to work around this, other than to set the poolSize
to 1 (so every query must use the same connection).
Here's the library we use for transactions - https://github.com/Shyp/pg-transactions. You won't have access to the helper methods - .find()
, .update()
etc but at least it's possible.
来源:https://stackoverflow.com/questions/27291992/sails-js-postgres-issue-with-transactions