web-dev-qa-db-ja.com

約束のあるKnexトランザクション

正しい出力を取得しています。実際、これら2つの操作は単一のトランザクションユニットとして扱われています。一方が失敗すると、両方が失敗します。

このコード例では、私はのトランザクションを行っています

(1)挿入(2)更新

私がそれに取り組む方法は、.dbn操作を.then内にネストすることです。私の質問は、このコードが誤って正しいかどうかです。私は約束と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
});

これは機能しますが、私はまだ何か間違っているように感じています。コメントを探しています。

14
david

外部チェーンがそれと連鎖するためには、内部クエリからpromiseを返す必要があります。

エラーを再スローしないため、エラーも飲み込みます。何が起こっているのかを明確にするため、.catch()を使用することをお勧めします。つまり、通常のtry-catchステートメント。

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
});

よりよく理解するために、「エミュレート」されている同期バージョンを次に示します。

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
}
31
Esailija