I am getting the correct output, and indeed, these two operations are being treated as a single transactional unit; where if one fails, both fail.
In this code example: i am doing a transaction of
(1) insert (2) update
The way I approach it is to nest my db operations inside the .then. My question is if this code is correct by accident? i am new to promises and knex.
knex.transaction(function(t) {
knex('foo')
.transacting(t)
.insert({id:"asdfk", username:"barry", email:"[email protected]"})
.then(function() {
knex('foo')
.where('username','=','bob')
.update({email:"[email protected]"})
.then(t.commit, t.rollback)
})
})
.then(function() {
// it worked
},
function() {
// it failed
});
This works, but I feel like I am doing something wrong still. Looking for comments.
Any failure will mean the database will rollback any queries executed on that connection to the pre-transaction state. Transactions are handled by passing a handler function into knex.transaction. The handler function accepts a single argument, an object which may be used in two ways:
Transactions are handled by passing a handler function into knex.transaction. The handler function accepts a single argument, an object which may be used in two ways: As an object passed into a query with and eventually call commit or rollback.
Notice that if a promise is not returned within the handler, it is up to you to ensure trx.commit, or trx.rollback are called, otherwise the transaction connection will hang. Calling trx.rollback will return a rejected Promise.
You need to return a promise from the inner query in order for the outer chain to be chained with that.
You also swallow any errors because you don't rethrow them - it's better to use .catch()
for this reason because it makes it more clearer what is happening - that is what would happen with normal try-catch
statement.
knex.transaction(function(t) {
return knex('foo')
.transacting(t)
.insert({id:"asdfk", username:"barry", email:"[email protected]"})
.then(function() {
return knex('foo')
.where('username','=','bob')
.update({email:"[email protected]"});
})
.then(t.commit)
.catch(function(e) {
t.rollback();
throw e;
})
})
.then(function() {
// it worked
})
.catch(function(e) {
// it failed
});
To understand it better, here's the synchronous version that is being "emulated":
try {
var t = knex.transaction();
try {
knex("foo")
.transacting(t)
.insert({id:"asdfk", username:"barry", email:"[email protected]"});
knex("foo")
.where('username','=','bob')
.update({email:"[email protected]"});
t.commit();
}
catch (e) {
t.rollback();
// As you can see, if you don't rethrow here
// the outer catch is never triggered
throw e;
}
// It worked
}
catch (e) {
//It failed
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With