防止IndexedDB请求错误取消事务

时间:2014-04-03 08:03:38

标签: javascript html5 transactions indexeddb

我的意图

循环遍历localStorage并将数据放入IndexedDB。 如果发生某些已知错误,例如当密钥已存在时出现ConstraintError,我想忽略这些特定错误,以便不中止事务。当请求触发错误时,中止事务是默认行为。

问题

我认为在请求onerror处理程序中使用event.preventDefault()会阻止这种情况发生。令人惊讶的是,事件仍然出现在事务的错误处理程序中!我可以通过打开日志记录来看到这种情况(参见下面的代码)。

transaction.onerror = function (event) {
    log('IndexedDb.migrateLocalStorage -> transaction -> onerror', event.target.error.name);
};
transaction.oncomplete = function () {
    log('IndexedDb.migrateLocalStorage -> transaction -> oncomplete');
};

for (var key in $W.localStorage) {

    if ($W.localStorage.hasOwnProperty(key)) {
        value = $W.localStorage.getItem(key);
        request = objectStore.add(addQuotesIfNecessary(value), key);
        request.onerror = function (event) {
            var error = event.target.error;
            log('IndexedDb.migrateLocalStorage -> request -> onerror', error, error.name);

            // do nothing if the same key exists in indexeddb. it is likely newer
            if (error.name === 'ConstraintError') { event.preventDefault(); }
        };
    }
}

2 个答案:

答案 0 :(得分:9)

似乎我粘贴的代码的日志记录输出让我误以为事务已中止,因为调用了transaction.onerror处理程序。但是,我没有记录的是,是否调用了transaction.onabort ......事实证明,调用event.preventDefault 实际上就足够了!

让我困惑的是错误传播到事务错误处理程序。 但是,交易没有中止!。它只是在阻止默认操作(中止)之后冒泡了事件。为了消除消息,我还需要调用event.stopPropagation以防止事件冒泡到事务的错误处理程序。请注意,如果您只需要取消该交易,则不一定非必要。

我在IDBRequst和IBTransaction的W3C文档中挖掘了答案。

答案 1 :(得分:1)

当事务内部出现问题时,事务是错误的。这就是事务存在的方式,以保持数据库的一致性。

在您的情况下,您最好首先检查密钥是否存在。如果是,则在其他情况下不执行任何操作即可插入数据。

另一个解决方案是为您要保存的每个对象打开一个事务....