与承诺Knex交易

我得到了正确的结果,实际上,这两个行动正在被视为一个单一的交易单位; 如果一个失败了,两个失败。

在这个代码示例中:我正在做一个事务

(1)插入(2)更新

我接近它的方式是将我的数据库操作嵌套在.then中。 我的问题是,如果这个代码是正确的意外? 我是新承诺和knex。

knex.transaction(function(t) { knex('foo') .transacting(t) .insert({id:"asdfk", username:"barry", email:"barry@bar.com"}) .then(function() { knex('foo') .where('username','=','bob') .update({email:"bob@foo.com"}) .then(t.commit, t.rollback) }) }) .then(function() { // it worked }, function() { // it failed }); 

这工作,但我觉得我仍然做错了什么。 寻找意见。

您需要从内部查询中返回一个承诺,以便将外部链与该链进行链接。

你也可以吞咽任何错误,因为你不重新抛出它们 – 使用.catch()出于这个原因会更好,因为它使得它更清晰 – 正常的try-catch语句会发生什么情况。

 knex.transaction(function(t) { return knex('foo') .transacting(t) .insert({id:"asdfk", username:"barry", email:"barry@bar.com"}) .then(function() { return knex('foo') .where('username','=','bob') .update({email:"bob@foo.com"}); }) .then(t.commit) .catch(function(e) { t.rollback(); throw e; }) }) .then(function() { // it worked }) .catch(function(e) { // it failed }); 

为了更好地理解它,下面是被“模拟”的同步版本:

 try { var t = knex.transaction(); try { knex("foo") .transacting(t) .insert({id:"asdfk", username:"barry", email:"barry@bar.com"}); knex("foo") .where('username','=','bob') .update({email:"bob@foo.com"}); 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 }