2013-12-20 476 views
1

在我當前的web應用程序中,顯示可以包含多個可編輯對象 - 從服務器獲取數據(然後存儲以供將來使用)或從本地IndexedDB對象存儲中提取數據。IndexedDB線程安全

這個我已經實現了,它完美地工作。然而,現在我想更進一步 - 在用戶需要使用它們時獲取本地不可用的數據可能會打破用戶工作的規律。

因此,我正在考慮在用戶希望與他們合作之前實現一個獲取服務器端數據的前瞻。這將工作的方式

  • 當應用程序啓動時,我產生了一個web工作人員觀看一個條目,稱之爲PreFetch,在它與主應用程序共享的IndexedDB中。
  • 用戶將鼠標懸停在可編輯的項目上,例如HTML標識abcd1234。
  • 在應用程序中,我將此ID添加到IndexedDB PreFetch鍵值 - 這是逗號分隔的ID列表。
  • Web工作人員週期性地拾取PreFetch CSV列表,然後重置它,並獲取那些本地不可用的數據並將它們存儲在對象庫中。

IndexedDB很好 - 毫無疑問。然而,我並不清楚我的計劃 - 有兩條線程更新同一個對象庫不會造成死鎖(或者更糟 - 將整個房屋撞到我的耳朵周圍)。

鑑於IndexedDB的操作的異步性,我關注的兩個類型的問題

一個。主線程正在寫入PreFetch鍵,同時工作人員正在刪除其內容。 b。主線程嘗試從IndexedDB中獲取數據,並決定「它不在那裏」,同時工作人員剛剛獲取這些數據並存儲它們。

前者有可能會破壞工作者驅動的數據預取的目的,而後者有可能觸發不必要的服務器流量來獲取已獲取的信息。

前者我可以避免使用localStorage共享PreFetch列表。後者我無法控制。

我的問題呢 - IndexedDB方法是線程安全嗎?谷歌搜索IndexedDB和線程安全沒有產生任何非常有用的,除了這個論壇上的一個或兩個職位。

我想過一種避免這個問題的方法 - 主線程和工作人員在嘗試讀取/寫入對象庫之前都檢查localStorage中的標誌變量。但是,我不清楚我需要這樣做。

回答

1

JavaScript只有一個線程,所以它是線程安全的。

使用事務進行同步鎖創建任務ID的對象存儲作爲枚舉'pending','working','done'的鍵和值。

如果對象存儲中不存在掛起值,生產者線程創建任務。消費者線程將待處理任務工作並在完成後更改完成。它應該工作。

您可以將webstorage更改事件用於頁面之間的同步鎖定,但不能與indexeddb一起使用。

+0

JavaScript是線程安全的,但是當你產生一個Worker時,你正在創建一個新的線程 - 在很多方面就像打開一個新的標籤,但不能訪問/ a DOM。你建議的同步鎖定想法或多或少是我原計劃要做的。但是,我曾計劃使用localStorage共享同步密鑰。鑑於IndexedDB操作的異步性質,我預見了以下情況 - 生產者決定操作是「掛起」的,但與此同時,消費者已經消失並將其標記爲「完成」。由於異步兩個十字架沒有任何對方的知識。 – DroidOS

+1

它不可能發生。寫交易是獨佔的。順便說一句,你在單個tx中使用讀取和寫入。 –