2014-12-06 52 views
2

,Tx是犯罪:IndexedDB的交易自動提交的邊緣情況的行爲

  • 請求成功回調函數返回 - 這意味着多個請求只能當一個請求是從成功回調執行事務邊界內執行前一個
  • 當你的任務返回到事件循環

這意味着,如果沒有請求提交給它,它不承諾,直到它返回到事件循環。通過

  • 放置一個新的IDB的要求從以前的請求的成功回調內排隊一個新的任務事件循環隊列,而不是在這種情況下,提交新的要求同步
    • :這些事實造成2個問題的狀態第一次成功回調立即返回,但另一個IDB請求已計劃
      • 是在單個初始事務中執行的所有異步請求嗎?這是在情況十分必要要實現的結果與背壓拉動地方消費讓你在未來的形式的反饋,這是準備消費的另一響應
  • 創建讀寫TX,不在返回事件循環之前放置任何請求並創建另一個請求
    • 確實創建了一個隱含地提交了前一個tx?如果不是這樣,可能會出現嚴重寫鎖STARVATIONS,因爲:

如果有多個「讀寫」交易正試圖訪問同一 對象存儲(即如果他們有重疊的範圍),交易 首先創建的事務必須是首先訪問對象存儲的 的事務。由於前面的 段落中的要求,這也意味着它是唯一具有 訪問對象庫的事務,直到事務完成。

通過遞歸請求提交與背壓從成功回調內排隊一個新的任務事件循環隊列的例子:

function recursiveFn(key) { 
     val req = store.get(key) 
     req.onsuccess = function() { 
     observer.onNext(req.result).onsuccess { recursiveFn(nextKey) } 
     } 
    } 

Observer#onNext // returns Future[Ack] Ack is either Continue or Cancel 

現在可以onsuccessonNext做的setTimeout(0 )還是不讓整個事情成爲一個交易的一部分?

獎金的問題:

我認爲只讀事務暴露給消費者/用戶,只是因爲它是很難檢測一個批次的讀取結束,如果你遞歸地從先前的成功回調提出的新要求一個權利?否則,我不認爲有任何其他原因讓他們接觸到用戶,對吧?

+0

您可以添加適當的鏈接到indexeddb規範嗎? – 2014-12-06 00:56:57

+0

我沒有,這是從我的頭上,並從過去數週的IndexedDb強烈體驗。 – lisak 2014-12-06 00:58:32

+0

Btw的IndexedDb開發人員在這裏回答了很多http://stackoverflow.com/q/10385364/306488 – lisak 2014-12-06 01:10:41

回答

2

我不確定我完全理解你的問題,但我會提供一個關於是否可以安全地使用IDB事務事件來移動狀態機的答案。

是的,沒有。理論上是,實踐中不行。

我想你明白了交易lifetime。但要rehash

一個交易的一生,只要它引用持續:它是「活動」,只要它是被引用後,它被認爲是「成品」,而事務被提交。

理論上,oncomplete應該在事務成功提交時觸發。有一個在spec一個有用的技巧就這一點,建議你怎麼可以循環:

要確定是否交易成功完成後,聽取了交易的完整的事件,而不是IDBObjectStore.add請求的成功事件,因爲交易在成功事件發生後仍然可能失敗。

爲了安全使用此機制,請務必注意非成功事件,包括onblockedonabort以及。

實際上,我發現交易在長時間或連續進行批量交易(如您在另一個IDB評論中注意到的)時會變成flaky。我通常不會設計我的應用程序以要求棘手的行爲,因爲無論規範如何表示它應該行爲,我都會在Firefox和Chromium中看到不可思議的事務(但主要是Blink,有趣),特別是在打開多個選項卡時。

我花了很多周重寫dash重用交易的假設表現收益。最後它甚至無法通過我的基本寫入測試,並且我被迫放棄同時/排隊/連續的交易並再次重寫。這次我選擇了一個一次處理一次的模型,但這對我來說比較慢,但對於我來說更可靠(並建議避免使用我的lib並使用像ydn這樣的大容量插入)。

我不確定您的應用程序需求,但我認爲將您的I/O綁定到事件循環似乎是一個災難性的想法。如果我需要一個事件循環,就像我所理解的那樣,我肯定會使用requestAnimationFrame()這個術語,並且如果我需要的數量少於每33毫秒一個,那麼就限制回調。

+0

我強調了最重要的部分。我需要知道的是,我是否可以在成功回調中執行'setTimeout(0)'而不提交事務。或者'setTimeout(0)'是否讓事務被提交? – lisak 2014-12-07 15:14:32

+0

我們不要考慮背壓問題。我只是感興趣,如果我可以安排('setTimeout(0)')在成功回調中的遞歸請求之後在一個事務中......通過「災難性的想法」你是指我在說什麼?那個不應該在成功回調中遞歸'setTimeout(0)'? – lisak 2014-12-07 15:30:40