2014-04-09 38 views
9

Sto ottenendo l'output corretto, e infatti, queste due operazioni vengono trattate come una singola unità transazionale; dove se uno fallisce, entrambi falliscono.Knex Transaction with Promises

In questo esempio di codice: sto facendo una transazione di

(1) Inserire (2) Aggiornamento

Il modo in cui mi avvicino è quello di nido mie operazioni db all'interno del .then. La mia domanda è se questo codice è corretto per caso? Sono nuovo alle promesse e al 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 
}); 

Questo funziona, ma sento che sto ancora facendo qualcosa di sbagliato. Alla ricerca di commenti.

+0

Puoi provare 1) l'aggiunta di alcuni console.logs dove il '// esso worked' e'// it failed' commenti sono, e 2) costringendo l'istruzione insert a fallire in qualche modo? Con il tuo annidamento corrente, il t.rollback viene chiamato solo quando l'aggiornamento fallisce, quindi immagino che non farebbe la cosa giusta se l'inserimento fallisse. – user3374348

risposta

21

È necessario restituire una promessa dalla query interna affinché la catena esterna sia concatenata con quella.

È inoltre possibile ingoiare gli errori perché non li si rilancia: è preferibile utilizzare .catch() per questo motivo perché rende più chiaro cosa sta succedendo, ovvero cosa succederebbe con la normale istruzione 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 
}); 

Per capire meglio, ecco la versione sincrona che viene "emulato":

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

Davvero utile, ma non ti sei perso una transazione sull'aggiornamento del 2 ° esempio? – Juan