2014-04-09 7 views
9

Otrzymuję prawidłowy wynik, i rzeczywiście, te dwie operacje są traktowane jako pojedyncza jednostka transakcyjna; gdzie, jeśli się nie uda, oba zawodzą.Transakcja Knex z obietnicami

W tym przykładzie kodu: Ja dokonuję transakcji

(1) wstawić (2) zaktualizuj

Sposób, w jaki podejście to jest gniazdo moje operacje db wewnątrz .Następnie. Moje pytanie brzmi, czy ten kod jest poprawny przez przypadek? Jestem nowy w obietnicach i 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 
}); 

To działa, ale mam wrażenie, że wciąż coś robię źle. Szukam komentarzy.

+0

możesz spróbować: 1) dodanie kilku console.logs gdzie '// to worked' i'// nieudane są komentarze i 2) wymuszenie instrukcji wstawiania w jakiś sposób nie działa? Przy obecnym zagnieżdżaniu, t.rollback jest wywoływany tylko wtedy, gdy aktualizacja się nie powiedzie, więc wyobrażam sobie, że nie zrobiłoby to dobrze, gdyby wstawka się nie powiodła. – user3374348

Odpowiedz

21

Musisz zwrócić obietnicę z wewnętrznego zapytania, aby łańcuch zewnętrzny był połączony z tym łańcuchem.

Połkniesz również wszystkie błędy, ponieważ ich nie powtarzasz - lepiej z tego powodu używać .catch(), ponieważ dzięki temu staje się on bardziej przejrzysty, co się dzieje - tak by się stało z normalną instrukcją 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 
}); 

Aby zrozumieć lepiej, oto synchroniczny wersja, która jest "emulować":

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 
} 
+0

Naprawdę pomocna, ale czy nie przeoczyłeś transakcji dotyczącej aktualizacji drugiego przykładu? – Juan