javascript - sailsjs - Las mejores prácticas de Sails.js en el uso de transacciones con promesas(Postgres)
sails github (2)
Actualmente estoy usando este flujo de trabajo exacto. Para ejecutar una consulta con promesas haz esto:
Model
.query(params)
.then(function(result){
//act on result
})
.catch(function(error){
//handle error
})
.done(function(){
//clean up
});
Para ejecutar múltiples consultas en paralelo, haga esto:
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
});
Si estás tratando de evitar anidar en tu código:
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
});
Nota: actualmente, la línea de flotación usa Q para promesas. Hay una solicitud de extracción para cambiar la línea de flotación de Q a bluebird aquí: waterline/bluebird
Cuando respondí a esta pregunta, aún no había tomado la clase de base de datos en la universidad, así que no sabía qué era una transacción. Hice algunas excavaciones y Bluebird te permite hacer transacciones con promesas. El único problema es que esto no está incluido en las velas, ya que se trata de un caso de uso especial. Aquí está el código que proporciona bluebird para esta situación.
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;
Estoy usando velas 0.9.16 con Postgres y mi pregunta es: ¿cuál es la mejor manera de ejecutar transacciones usando la API actual con promesas? Puede ser que haya algo mejor que:
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(...);
})
}
})
¡Gracias por la ayuda!
La mejor manera de lidiar con las transacciones es cuando están envueltas apropiadamente por una biblioteca de promesas, ya que la lógica de las transacciones se asigna perfectamente a la cadena de eventos de promesas, por lo que no tiene que preocuparse de cuándo hacer COMMIT
o ROLLBACK
, como sucede automáticamente.
Aquí hay un ejemplo completo de cómo funciona con la biblioteca 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;
});