【问题标题】:IndexedDB and large amount of inserts on Angular appAngular 应用程序上的 IndexedDB 和大量插入
【发布时间】:2016-02-09 06:03:57
【问题描述】:

我正在努力处理来自服务器的 20-50k JSON 对象响应,我应该将其插入到我们的 indexeddb 数据存储中。

使用 foreach 重复响应,并添加每一行。响应少于 10k 行的调用工作正常,并在一分钟左右插入。但是当金额变大时,数据库会在一段时间后无响应并返回此错误消息

“db Error err=transaction aborted for unknown reason”

我正在为数据库使用 Dexie 包装器,并为名为 ngDexie 的 dexie 使用角度包装器。

var deferred = $q.defer();
var progress = 0;
 // make the call
 $http({
       method: 'GET',
       headers: headers,
       url: '/Program.API/api/items/getitems/' + user
            }).success(function (response) {

        // parse response
        var items = angular.fromJson(response);
        // loop each item
        angular.forEach(items, function (item) {    
                    // insert into db
                    ngDexie.put('stuff', item).then(function () {
                        progress++;
                        $ionicLoading.show({
                            content: 'Loading',
                            animation: 'fade-in',
                            template: 'Inserting items to db: ' + progress
                                       + '/' + items.length,
                            showBackdrop: true,
                            maxWidth: 200,
                            showDelay: 0

                        });

                        if (progress == items.length) {
                            setTimeout(function () {
                                $ionicLoading.hide();
                            }, 500);
                            deferred.resolve(items);

                        }      
                    });
                });
            }).error(function (error) {
                $log('something went wrong');
                $ionicLoading.hide();
            });
            return deferred.promise;

我是否有错误的方法来处理一个块中的整个数据?有没有更好的选择?整个过程只在用户打开网站时执行一次。非常感谢所有帮助。目标设备是运行 Android 和 Chrome 的平板电脑。

【问题讨论】:

    标签: javascript json angularjs indexeddb dexie


    【解决方案1】:

    由于您遇到未知错误,因此 I/O 出现了问题。我的猜测是下面的数据库在处理大量数据时遇到了麻烦。可以尝试分批拆分,每批最多 10k。

    事务可能由于与特定 IDBRequest 无关的原因而失败。例如,由于提交事务时的 IO 错误,或者由于遇到配额限制,实现无法将超出配额与特定请求联系起来。在这种情况下,实现必须运行用于中止事务的步骤,使用事务作为事务并将适当的错误类型作为错误。例如,如果超过配额,则应将 QuotaExceededError 用作错误,如果发生 IO 错误,则应将 UnknownError 用作错误。

    你可以在specs找到这个

    另一种可能性,您是否在对象存储上定义了任何索引?因为对于您拥有的每个索引,每次插入都需要维护该索引。

    【讨论】:

    • 感谢您抽出宝贵时间回答,我应该对此进行更多研究,但我们有一位热切的客户希望明天上线。我现在将尝试制作每个 5k 的块并祈祷它能够正常工作。是的,我们定义了索引。我不是 IndexedDB 的经验丰富的用户,因为这是一个快速项目,那么维护它们是什么意思?
    • 在 indexeddb 中的索引实际上也是对象存储,唯一的区别是这个对象存储的键是在索引上定义的键路径的值,值是匹配的对象的集合键
    【解决方案2】:

    如果您插入许多新记录,我建议您使用 add。这是出于性能原因添加的。请参阅此处的文档:

    https://github.com/FlussoBV/NgDexie/wiki/ngDexie.add

    【讨论】:

      【解决方案3】:

      我遇到了大容量插入问题(100.000 - 200.000 条记录)。我已经使用 Dexie 库中的 bulkPut() 解决了我所有的 IndexedDB 性能问题。它有一个重要的特点:

      Dexie 的表现非常出色。它的批量方法利用 indexedDB 中一个不为人知的特性,它可以存储 不听每一个 onsuccess 事件的东西。这加快了 性能发挥到极致。

      德西:https://github.com/dfahlander/Dexie.js

      BulkPut() -> http://dexie.org/docs/Table/Table.bulkPut()

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-11-11
        • 1970-01-01
        • 2012-05-15
        • 2015-02-06
        • 1970-01-01
        • 2021-12-27
        • 1970-01-01
        相关资源
        最近更新 更多