Sails.js使用Promises(Postgres)事务的最佳实践

我正在使用0.9.16的PostgreSQL风帆和我的问题是:什么是最好的方式来执行交易使用当前的API承诺? 可能会有比以下更好的东西:

Model.query('BEGIN TRANSACTION', function (err) { if (err) { next(err); } else { Model .create(...) .(function (value) { return [value, RelatedModel.create(...).then(...)]; }) .fail(function (err) { Model.query('ROLLBACK'); next(err); }) .spread(function (...) { Model.query('COMMIT') next(...); }) } }) 

感谢帮助!

我正在使用这个确切的工作stream程。 使用promise执行一个查询,请执行以下操作:

 Model .query(params) .then(function(result){ //act on result }) .catch(function(error){ //handle error }) .done(function(){ //clean up }); 

要并行执行多个查询,请执行以下操作:

 var Promise = require('q'); Promise.all([ User.findOne(), AnotherModel.findOne(), AnotherModel2.find() ]) .spread(function(user,anotherModel,anotherModel2){ //use the results }) .catch(function(){ //handle errors }) .done(function(){ //clean up }); 

如果您试图避免在代码中嵌套:

 Model .query(params) .then(function(result){//after query #1 //since you're returning a promise here, you can use .then after this return Model.query(); }) .then(function(results){//after query#2 if(!results){ throw new Error("No results found in query #2"); }else{ return Model.differentQuery(results); } }) .then(function(results){ //do something with the results }) .catch(function(err){ console.log(err); }) .done(function(){ //cleanup }); 

注意:目前,水线使用Q作为承诺。 有一个拉线请求,将水线从Q线切换到蓝鸟: 水线/蓝鸟

当我回答这个问题时,我还没有上大学的数据库课,所以我不知道交易是什么。 我做了一些挖掘,蓝鸟允许你做承诺交易。 唯一的问题是,这不是完全内置于风帆,因为它是一个什么样的特殊用例。 这里是蓝鸟为这种情况提供的代码。

 var pg = require('pg'); var Promise = require('bluebird'); Promise.promisifyAll(pg); function getTransaction(connectionString) { var close; return pg.connectAsync(connectionString).spread(function(client, done) { close = done; return client.queryAsync('BEGIN').then(function () { return client; }); }).disposer(function(client, promise) { if (promise.isFulfilled()) { return client.queryAsync('COMMIT').then(closeClient); } else { return client.queryAsync('ROLLBACK').then(closeClient); } function closeClient() { if (close) close(client); } }); } exports.getTransaction = getTransaction; 

处理事务的最好方法是当它们被承诺库正确包装时,因为事务逻辑完全映射到承诺事件链中,所以不必担心何时自动执行COMMITROLLBACK

下面是一个完整的pg-promise库的例子:

 var pgp = require('pg-promise')(/*options*/); var cn = "postgres://username:password@host:port/database"; var db = pgp(cn); // database instance; db.tx(t => { // BEGIN has been executed return t.batch([ t.one("insert into users(name) values($1) returning id", 'John'), t.one("insert into users(name) values($1) returning id", 'Mike') ]); }) .then(data => { // COMMIT has been executed console.log(data[0].id); // print id assigned to John; console.log(data[1].id); // print id assigned to Mike; }) .catch(error => { // ROLLBACK has been executed console.log(error); // print why failed; });