2014-12-06 61 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