Knex的事务回滚问题

时间:2019-06-25 19:29:43

标签: node.js promise knex.js

我正在尝试在节点js中使用knex进行mysql事务。我的SQL事务看起来像这样

1-检查公司名称是否存在,如果存在,则提示错误并回滚事务。

2-检查电子邮件地址是否存在,如果是,则提示错误并回滚事务。

3-插入用户表,公司表和用户角色表,如果遇到错误则回滚事务。

现在,我观察到,如果嵌套内发生错误,则尤其是最后一个错误,则事务不会回滚,而是提交先前的事务。

这是我的功能代码

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)


  })


我在这里做错什么了吗?

1 个答案:

答案 0 :(得分:1)

将事务与knex一起使用时,您需要告诉每个查询它应转到给定的事务。

因此,您应该编写knex('table').insert({...}}),而不是执行t('table').insert({...}})(后者从池中分配了新的连接),它将向运行事务的连接发送查询。

如果您还从

返回承诺,
knex.transaction(trx => {
  return trx('table').insert({...});
})

您不得调用由knex隐式调用的显式trx.commit() / trx.rollback(),其结果/拒绝返回的promise的值。