2014-04-09 20 views
9

Tôi nhận được kết quả chính xác, và thực sự, hai hoạt động này đang được coi là một đơn vị giao dịch duy nhất; nếu một thất bại, cả hai đều thất bại.Giao dịch Knex với Lời hứa

Trong ví dụ mã này: tôi đang làm một giao dịch của

(1) chèn (2) cập nhật

Con đường tôi tiếp cận nó là tổ hoạt động db của tôi bên trong .Sau đó. Câu hỏi của tôi là nếu mã này là chính xác do tai nạn? tôi mới đến lời hứa và 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 
}); 

Tác phẩm này, nhưng tôi cảm thấy như tôi đang làm điều gì đó sai. Đang tìm kiếm nhận xét.

+0

Bạn có thể thử 1) thêm một số console.logs nơi '// nó worked' và '//nó thất bại' bình luận được, và 2) buộc tuyên bố chèn để thất bại bằng cách nào đó? Với tổ hợp hiện tại của bạn, t.rollback chỉ được gọi khi cập nhật không thành công, vì vậy tôi tưởng tượng nó sẽ không làm điều đúng nếu chèn không thành công. – user3374348

Trả lời

21

Bạn cần trả lại lời hứa từ truy vấn bên trong để chuỗi bên ngoài bị xích với điều đó.

Bạn cũng nuốt bất kỳ lỗi nào vì bạn không nghĩ lại chúng - tốt hơn nên sử dụng .catch() vì lý do này rõ ràng hơn những gì đang diễn ra - đó là điều sẽ xảy ra với câu lệnh try-catch bình thường.

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

Để hiểu nó tốt hơn, đây là phiên bản đồng bộ đang được "mô phỏng":

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

Thực sự hữu ích, nhưng bạn không bỏ lỡ một giao dịch trên bản cập nhật của ví dụ thứ 2? – Juan

Các vấn đề liên quan