Reputation: 14571
I need to run multiple operations against the database and I need to fit them all into a transaction. Here is how I do things and from my testing it does not seem to be right.
Basically for each operation I have a function that returns the knex promise. Based on the parameter, there may be no need to actually do anything, for instance, if there are not any rows to insert, I don't need to do anything
function insertRows(rowsToInsert, trx){
if (rowsToInsert && rowsToInsert.length>0){
return knex.batchInsert(...).transacting(trx)
}else{
//no need to run
return Promise.resolve() //this is probably wrong
}
}
//I am returning a promise as I yield
this function in a co
function process(params){
return new Promise(function (resolve, reject){
knex.transaction(function(trx){
return insertRows(rows, trx)
.then(function (result){
return insertRows(rows2,trx)
}).then(function (result){
return updateRows(rows3,trx)
})
}
}
}
Running in this way I have noticed that sometimes I can get a deadlock between one update and one insert so that makes me believe that my operations don't happen one after another but maybe in parallel? How should I handle:
then()
when rows is empty so just skip to the next then()
Upvotes: 2
Views: 2831
Reputation: 1460
In agreement with @Mikael , you don't need the new Promise
, but also I think you need to return knex.transaction(
, so that that the transaction function is completed before additional processing is done?
function process(params){
return knex.transaction(function(trx){
return insertRows(rows, trx)
}).then(function (result){
return insertRows(rows2,trx)
}).then(function (result){
return updateRows(rows3,trx)
});
}
Since you didn't return knex.transaction()
, this operation will be 'disconnected' from the caller's sequence, running asynchronously.
Your return Promise.resolve() //this is probably wrong
is fine. You are returning a resolved promise in the else
, just like in the if
portion of the function. Because that (sub)function is only called within a Promise
... .then
, you could actually omit the else
clause, because the .then
statement automatically converts synchronous function return values into resolved promises.
Upvotes: 3