2012-01-27 4 views
8

Обзор: Я стараюсь избегать условий гонки с доступом к IndexedDB как с веб-страницы, так и с веб-работника.Доступ к IndexedDB из нескольких тем javascript

Установка: Веб-страница, которая сохраняет элементы локального IndexedDB, когда пользователь работает с сайтом. Всякий раз, когда пользователь сохраняет данные в локальный БД, запись помечена как «Отказано».

Фоновый поток веб-работника, который извлекает данные из IndexedDB, отправляет их на сервер и как только сервер получает его, маркируя данные в IndexedDB как «Отправленные».

Проблема: Поскольку доступ к индексированной асинхронный, я не могу гарантировать, что пользователь не будет обновлять записи в то же время веб-работник отправляет его на сервер. График показан ниже:

  1. Web-работник получает данные из БД и отправляет его на сервер
  2. Хотя передача происходит, пользователь обновляет данные сохранение его в БД.
  3. Веб-работник получает ответ от сервера, а затем обновляет БД в «Отправленные»
  4. Существует теперь данные в БД, которые не были отправлены на сервер, но помечены как «Отправленные»

Сбой После получения ответа от сервера, я могу перепроверять строку, чтобы увидеть, было ли что-либо изменено. Однако я все еще остаюсь маленьким окном, где данные могут быть записаны в БД, и он никогда не будет отправлен на сервер.

Пример: После сервера говорит данные сохраняются, то:

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

Другие ноты: Существует синхронизации апи в соответствии со спецификацией W3, но ни один не реализовали еще, чтобы он мог не используется (http://www.w3.org/TR/IndexedDB/#sync-database). Sync api был разработан для использования веб-работниками, чтобы избежать этой конкретной ситуации, которую я бы предположил.

Любые мысли об этом были бы очень признательны. Работали над ним около недели и не смогли придумать что-нибудь, что сработает.

ответ

2

Я думаю, что на этот раз я нашел работу. Не совсем так чисто, как хотелось бы, но, похоже, это потокобезопасный.

Я начинаю с хранения даты и времени в поле LastEdit, когда я обновляю данные. Веб-сайт, я размещаю сообщение в браузере.

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

Затем в браузере я обновляю свой флаг отправки, если последняя дата изменения не изменилась.

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

Поскольку это все сделано в транзакции в браузере, оно работает нормально. Как только браузер поддерживает Sync API, я все равно могу выбросить его.

0

Можете ли вы использовать транзакцию?
https://developer.mozilla.org/en/IndexedDB/IDBTransaction

+0

Я не думаю, что вы можете получить доступ к IndexedDB без использования транзакции. Проблема заключается в том, что транзакция не останется открытой, пока я отправляю данные на сервер. – Shawn

Смежные вопросы