18

只要您使用适当的 IDBTransaction,是否可以从单个事务中完成所有这些操作,而不是打开多个事务(读取表、写入表、写入另一个表等)?

Mozilla 说:“保持事务处于活动状态的唯一方法是对其发出请求。当请求完成时,您将收到一个 DOM 事件,并且假设请求成功,您将有另一个机会来扩展事务在那次回调期间。” 这有点模糊。这是否意味着如果我为 DOM 回调提供了一个事件处理程序,我可以在该回调的任何时候使用该事务,而不必担心事务被关闭?

https://developer.mozilla.org/en/IndexedDB/Using_IndexedDB#Adding_data_to_the_database

4

4 回答 4

35

简短回答:如果您为“成功”或“错误”事件提供事件处理程序,您可以在该事件处理程序中放置一个新请求,而不必担心事务会自动关闭。

长答案:事务提交通常应该是完全透明的。唯一的规则是你不能在做非数据库“东西”时保持事务打开。即你不能开始一个事务,然后在做一些 XMLHttpRequests 或者等待用户点击一个按钮的时候让它保持打开状态。

一旦您停止对事务发出请求并且最后一个请求回调完成,事务就会自动关闭。

但是,您可以启动一个事务,使用该事务读取一些数据,然后写入一些结果。

因此,请确保在开始事务之前拥有所需的所有数据,然后在请求回调中执行您想要执行的所有读取和写入操作。完成后,交易将自动完成。

于 2012-06-15T22:48:09.330 回答
12

IndexedDB 事务在最后一个回调被触发后立即提交,因此保持它们活动的方法是通过回调传递它们。

我从 Jonas Sicking 那里获取我的交易信息,Jonas Sicking 是一名 Mozilla 开发人员和 IndexedDB 的共同规范作者,他在这篇出色的博客文章中发表了以下评论:

以下句子不正确“当事务变量超出范围并且不能再针对它放置更多请求时,今天的事务会自动提交”。

当变量超出范围时,事务永远不会自动提交。通常,它们仅在最后一个成功/错误回调触发并且该回调不再安排更多请求时提交。所以它与任何变量的范围无关。

唯一的例外是,如果您创建了一个事务但没有对它提出任何请求。在这种情况下,只要您返回事件循环,事务就会“提交”(无论这对于没有请求的事务意味着什么)。在这种情况下,只要对事务的所有引用超出范围,您就可以在技术上“提交”事务,但这并不是一个特别有趣的优化用例。

于 2012-05-01T22:19:16.310 回答
3

简短的回答:不要保留。

为了防止竞争条件,IndexedDB 是为隐式提交而设计的,因此您不能显式地保持事务处于活动状态。如果需要,请更改您的算法,使其不需要保持活动状态。

重用事务以提高性能并执行有序请求。在这些情况下,事务将隐式保持活动状态。

于 2013-05-27T07:31:19.107 回答
0

要保持事务处于活动状态,请从完成操作的回调中继续执行下一个操作。请参考以下示例代码。

function put_data(db,tableName,data_array)
{
    var objectStore=db.transaction([tableName],"readwrite").objectStore(tableName);
    put_record(data_array,objectStore,num_rows,0);
}

function put_record(data_array,objectStore,row_index)
{
    if(row_index<data_array.length)
    {
        var req=objectStore.put(data_array[row_index]);
        req.onsuccess=function(e)
        {
            row_index+=1;
            put_record(data_array,objectStore,row_index);
        };
        req.onerror = function()
        {
            console.error("error", this.error);
            row_index+=1;
            put_record(data_array,objectStore,row_index);
        };
    }
}
于 2014-12-20T11:38:27.557 回答