2013-05-03 21 views
11

Khi tôi sử dụng transaction() để cập nhật một vị trí, dữ liệu tại địa điểm đó là trở rỗng mặc dù vị trí có một số dữ liệu.căn cứ hỏa lực giao dịch gọi api dữ liệu hiện tại là null

Tôi đã thử transaction()sau khi đọc dữ liệu tại cùng một vị trí tại thời điểm nó cung cấp tất cả dữ liệu tại vị trí đó.

Tôi có thể sử dụng transaction() nếu trường hợp như thế nào?

Trả lời

20

Giao dịch hoạt động theo cách của SimpleDB của Amazon hoặc một cụm cơ sở dữ liệu bị phân mảnh. Đó là để nói, họ "cuối cùng nhất quán" hơn là đảm bảo phù hợp. Vì vậy, khi bạn đang sử dụng các giao dịch, hàm xử lý có thể được gọi nhiều hơn một lần với một giá trị cục bộ (trong một số trường hợp null nếu nó không bao giờ được truy xuất) và sau đó lại với giá trị được đồng bộ hóa (bất kỳ trên máy chủ).

Ví dụ:

pathRef.transaction(function(curValue) { 

    // this part is eventually consistent and may be called several times 

}, function(error, committed, ss) { 

    // this part is guaranteed consistent and will match the final value set 

}); 

Đây thực sự là những suy nghĩ mà bạn phải tiếp cận giao dịch anyways. Bạn nên luôn mong đợi nhiều cuộc gọi, vì giao dịch đầu tiên có thể va chạm với một thay đổi khác và bị từ chối. Bạn không thể sử dụng phương thức xử lý của giao dịch để tìm nạp giá trị máy chủ (mặc dù bạn có thể đọc nó ra khỏi cuộc gọi lại thành công).

Ngăn chặn sự kiện kích hoạt tại địa phương

Khi giao dịch xảy ra, một sự kiện địa phương được kích hoạt trước khi nó đạt đến máy chủ cho đền bù độ trễ. Nếu giao dịch không thành công, sự kiện cục bộ sẽ được hoàn nguyên (thay đổi hoặc xóa sự kiện được kích hoạt).

Bạn có thể sử dụng thuộc tính applyLocallyon transactions để ghi đè hành vi này, làm cho kết quả cục bộ chậm hơn nhưng đảm bảo rằng chỉ giá trị máy chủ được kích hoạt cục bộ.

pathRef.transaction(function(curValue) { 

    // this is still called multiple times 

}, function(error, committed, ss) { 

    // this part is guaranteed consistent and will match the final value set 

}, 
    // by providing a third argument of `true`, no local event 
    // is generated with the locally cached value. 
true); 
+0

Cảm ơn, tôi đã sử dụng giao dịch gần 3 ngày sau khi dữ liệu được chèn vào. Vì vậy, bạn nói để sử dụng giao dịch đầu tiên chúng ta cần phải kiểm tra vị trí đó cho dù bất kỳ giá trị tồn tại hay không? – Ashok

+0

"Cuối cùng liên tục" không có gì để làm với chiều dài nó được trên máy chủ, chỉ là chiều dài nó đã được trên máy khách - nó không phải trên máy khách cho đến khi bạn yêu cầu nó. Bạn không nhất thiết cần phải kiểm tra xem một giá trị có tồn tại hay không, chỉ cần chấp nhận rằng hàm có thể được gọi nhiều lần và "cuối cùng" sẽ được gọi với giá trị máy chủ. – Kato

+0

@Kato Tôi lấy nó sau đó giao dịch đó sẽ là một điều xấu cho một máy chủ Node để sử dụng để giảm số dư của người dùng?Như một máy chủ nút khác tạo ghi trước, sau đó tôi muốn nó viết cùng một thứ (do đó thiết lập sẽ tốt hơn?) –

7

Bạn cần phải làm theo mô hình này:

var pinRef = firebase.database().ref('vm-pin-generator'); 
pinRef.transaction(function(oldPin) { 
    // Check if the result is NOT NULL: 
    if (oldPin != null) { 
     return localPinIncrementor(oldPin); 
    } else { 
     // Return a value that is totally different 
     // from what is saved on the server at this address: 
     return 0; 
    } 
}, function(error, committed, snapshot) { 
    if (error) { 
     console.log("error in transaction"); 
    } else if (!committed) { 
     console.log("transaction not committed"); 
    } else { 
     console.log("Transaction Committed"); 
    } 
}, true); 

căn cứ hỏa lực thường trả về một giá trị null trong khi lấy một chìa khóa cho lần đầu tiên nhưng trong khi lưu nó kiểm tra nếu giá trị mới cũng tương tự như giá trị cũ hoặc không phải. Nếu không, firebase sẽ chạy toàn bộ quá trình một lần nữa, và lần này giá trị chính xác được trả về bởi máy chủ.

Thêm null kiểm tra và trả lại giá trị hoàn toàn không mong muốn (0 trong trường hợp này) sẽ làm cho Firebase chạy chu trình một lần nữa.

+1

đây phải là câu trả lời đúng. – martinjbaker

+0

Thay vì trả về 0, bạn có thể trả lại không xác định để hủy giao dịch. "Nếu không xác định được trả lại (tức là bạn quay trở lại không có đối số), giao dịch sẽ bị hủy và dữ liệu tại vị trí này sẽ không bị sửa đổi". https://firebase.google.com/docs/reference/admin/node/admin.database.Reference#transaction –

+0

Tôi không biết liệu có điều gì đó đã thay đổi trong Firebase vì câu trả lời này đã được viết hay chưa, nhưng nếu tôi trả lại không xác định hoặc không có gì , Firebase bị treo trong 60 giây và sau đó hết giờ. Tôi đoán kết quả ròng là như nhau, nhưng nó không có vẻ giống như một điều tốt để làm. –