2014-04-09 1 views
9

Ich bekomme die richtige Ausgabe, und tatsächlich werden diese beiden Operationen als eine einzige Transaktionseinheit behandelt; wo, wenn einer versagt, beide versagen.Knex Transaktion mit Promises

In diesem Codebeispiel: i eine Transaktion von

tue

(1) einfügen (2) aktualisiert

So wie ich es Ansatz zu nisten im Inneren des .then meine db ist Operationen. Meine Frage ist, ob dieser Code zufällig ist? Ich bin neu zu Versprechen und 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 
}); 

Das funktioniert, aber ich fühle mich, als würde ich immer noch etwas falsch machen. Auf der Suche nach Kommentaren.

+0

können Sie versuchen, 1) das Hinzufügen einiger console.logs wo die '// es worked' und'// es ist fehlgeschlagen' Kommentare sind, und 2) erzwingt die Insert-Anweisung irgendwie fehlschlagen? Mit Ihrer aktuellen Verschachtelung wird die t.rollback nur aufgerufen, wenn das Update fehlschlägt, also würde ich mir vorstellen, dass es nicht das Richtige tun würde, wenn das Einfügen fehlschlägt. – user3374348

Antwort

21

Sie müssen ein Versprechen aus der inneren Abfrage zurückgeben, damit die äußere Kette damit verkettet wird.

Sie schlucken auch alle Fehler, weil Sie sie nicht wiederholen - es ist besser, .catch() aus diesem Grund zu verwenden, weil es klarer macht, was passiert - das ist, was mit normalen try-catch Aussage passieren würde.

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

es Um besser zu verstehen, hier ist die synchrone Version, die "emuliert" wird:

try { 
    var t = knex.transaction(); 
    try { 
     knex("foo") 
      .transacting(t) 
      .insert({id:"asdfk", username:"barry", email:"b[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

Wirklich hilfreich, aber haben Sie eine Transaktion zum Update des 2. Beispiels nicht verpasst? – Juan