简体   繁体   中英

Transaction rollback issue with knex

I am trying to do mysql transactions using knex in node js. My SQL transactions look like this

1- Check if company name exists, if yes then prompt error and rollback transaction.

2- Check if email address exists, if yes then prompt error and rollback transaction.

3- Insert into user, company and userroles tables and if error encountered rollback transaction.

Now I observe that if error occurs inside nested then especially the lastone then transaction doesn't rollback instead it commits previous transactions.

Here is my function code

return knex.transaction(function(t){
        return knex('company').where({ companyname: companyname }).select('companyid')
        .then(function(rows){
            if(rows.length >= 1)
                return Promise.reject('company already exist');
            return knex('Users').where({email: emailaddress}).select('userid')
        })
        .then(function(rows){
            if(rows.length >=1 )
                    return Promise.reject('user already exist');

            return knex('Users').insert({username:username,email:emailaddress,passsword:password,creationtime:'2008-11-11 13:23:44',updationtime:'2008-11-11 13:23:44'},'userid')

        })
        .then(function(useridreturned){
            userid=useridreturned;
            return knex('company').insert({companyname:companyname,companytokens:100})

        })
        .then(function(companyidreturn){
            companyid=companyidreturn;
            return knex('userroles').insert({userid:userid[0],roleid:1,companyid:companyid[0]},'userrolesid')

        })
        .then(function(result){
            return Promise.resolve('Account Created');
        })
        .then(t.commit)
        .catch(t.rollback)


  })


Am I doing something wrong here ?

When using transactions with knex, you need to tell to every query that it should go to given transaction.

So instead of doing knex('table').insert({...}}) (which allocated new connection from pool) you should write t('table').insert({...}}) which will send query to the connection where transaction is going on.

Also if you are returning promise from

knex.transaction(trx => {
  return trx('table').insert({...});
})

You must not call explicit trx.commit() / trx.rollback() those are called by knex implicitly with result / reject value of the returned promise.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM