2012-01-27 40 views
8

Tổng quan: Tôi đang cố gắng tránh điều kiện chủng tộc khi truy cập vào IndexedDB từ cả trang web và nhân viên web.Truy cập vào IndexedDB từ nhiều chủ đề javascript

Thiết lập: Trang web lưu các mục vào IndexedDB cục bộ khi người dùng làm việc với trang web. Bất cứ khi nào người dùng lưu dữ liệu vào DB cục bộ, bản ghi sẽ được đánh dấu là "Chưa gửi".

Chủ đề nền công nhân Web đang lấy dữ liệu từ IndexedDB, gửi nó đến máy chủ và khi máy chủ nhận được, đánh dấu dữ liệu trong IndexedDB là "Đã gửi".

Vấn đề: Kể từ khi truy cập vào các IndexedDB là không đồng bộ, tôi không thể đảm bảo rằng người dùng sẽ không cập nhật một kỷ lục đồng thời các web công nhân đang gửi nó đến máy chủ. Các mốc thời gian được hiển thị dưới đây:

  1. Web nghiệp nhận dữ liệu từ DB và gửi nó đến máy chủ
  2. Trong khi việc chuyển nhượng đang xảy ra, người dùng cập nhật các dữ liệu lưu nó vào DB.
  3. Web-công nhân nhận được phản hồi từ máy chủ và sau đó cập nhật DB để "gửi"
  4. Có bây giờ dữ liệu trong DB mà chưa được gửi đến máy chủ nhưng đánh dấu là "Sent"

Không giải pháp: Sau khi nhận được phản hồi từ máy chủ, tôi có thể kiểm tra lại hàng để xem có bất kỳ điều gì đã bị thay đổi không. Tuy nhiên tôi vẫn còn lại với một cửa sổ nhỏ, nơi dữ liệu có thể được ghi vào DB và nó sẽ không bao giờ được gửi đến máy chủ.

Ví dụ: Sau khi máy chủ nói dữ liệu được lưu, sau đó:

IndexedDB.HasDataChanged(
    function(changed) { 
     // Since this is async, this changed boolean could be lying. 
     // The data might have been updated after I checked and before I was called. 
     if (!changed){ 
      IndexedDB.UpdateToSent() } 
    }); 

ghi chú khác: Có một api đồng bộ theo spec W3, nhưng không ai đã thực hiện nó chưa vì thế nó có thể không được sử dụng (http://www.w3.org/TR/IndexedDB/#sync-database). Api đồng bộ được thiết kế để được sử dụng bởi các công nhân web, để tránh tình trạng chính xác này tôi sẽ giả định.

Bất kỳ suy nghĩ nào về điều này sẽ được đánh giá cao. Đã được làm việc trên nó trong khoảng một tuần và đã không thể đến với bất cứ điều gì mà sẽ làm việc.

Trả lời

2

Tôi nghĩ rằng tôi đã tìm được một công việc xung quanh việc này ngay bây giờ. Không thực sự sạch sẽ như tôi muốn, nhưng nó có vẻ là chủ đề an toàn.

Tôi bắt đầu bằng cách lưu trữ datetime vào trường LastEdit, bất cứ khi nào tôi cập nhật dữ liệu. Từ nhân viên web, tôi đăng một tin nhắn lên trình duyệt.

self.postMessage('UpdateDataSent#' + data.ID + '#' + data.LastEdit); 

Sau đó, trong trình duyệt tôi cập nhật cờ đã gửi, miễn là ngày chỉnh sửa cuối cùng không thay đổi.

// Get the data from the DB in a transaction 
if (data.LastEdit == lastEdit) 
{ 
    data.Sent = true; 
    var saveStore = trans.objectStore("Data"); 
    var saveRequest = saveStore.put(data); 
    console.log('Data updated to Sent'); 
} 

Vì điều này được thực hiện trong giao dịch ở phía trình duyệt, có vẻ như nó hoạt động tốt. Một khi các trình duyệt hỗ trợ Sync API, tôi có thể vứt nó đi.

0

Bạn có thể sử dụng giao dịch không?
https://developer.mozilla.org/en/IndexedDB/IDBTransaction

+0

Tôi không nghĩ rằng bạn có thể truy cập vào IndexedDB mà không cần sử dụng giao dịch. Vấn đề là giao dịch sẽ không được mở trong khi tôi gửi dữ liệu đến máy chủ. – Shawn

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