代码之家  ›  专栏  ›  技术社区  ›  Alexander Tsepkov

对PookDB的高频更新(文档更新冲突)

  •  0
  • Alexander Tsepkov  · 技术社区  · 8 年前

    我有一种获取/更新状态的方法,该状态存储在PockDB中。此方法由元素的构造函数调用,以向元素分配用户友好的唯一标记。代码的简化版本如下所示:

    var tagList = [ /* set of dictionary words to cycle through */ ];
    function generateTag(id) {
        return db.get('tags').then(function (tagData) {
            var tag = '', remainder = tagData.tagCount, quotient;
    
            while (remainder >= tagList.length) {
                quotient = Math.floor(remainder / tagList.length);
                tag += tagList[quotient - 1];
                remainder -= tagList.length * quotient;
            }
            tag += tagList[remainder];
            tag = tag.charAt(0).toLowerCase() + tag.slice(1);
    
            tagData.tagCount++;
            tagData.tags[tag] = id;
    
            db.put(tagData);
            return tag;
        }).catch(function (err) {
            console.error(err);
        });
    }
    
    class Element {
        constructor() {
            var self = this;
            generateTag('element' + Date.now()).then(function (tag) {
                self.tag = tag;
            });
        }
    }
    

    当创建元素之间存在延迟时,此逻辑按预期工作。但当在快速突发(即for循环)中创建元素时 db.get 在调用之前调用第二、第三和连续元素 db.put 第一个元素的操作完成,导致连续元素的“文档更新冲突”消息。起初,我以为PockDB的冲突解决方案会自动为我处理这个问题,但我错了。

    也许我不理解处理此类案件的正确方式,或者有更好的方式写这篇文章吗?我需要的是连续的 db.get 呼叫有效阻止,直到正在进行 db.put 从上一个操作结束。我在想,也许甚至可以保持一个静态链接,指向对应于“标签”对象上的最后一次PockDB操作的promise,这样 db.get('tags') 我会跑 tagsPromise.then(function () { return db.get('tags'); }) ,但我仍然是一个有承诺的新手,不知道这是否是解决这个问题的理想方式,或者这个问题是否是一个真正的问题,或者是我通过不坚持更好的方法强加给自己的东西?

    更新: 它看起来像是修改了逻辑,总是返回一个promise,总是以“singleton”promise开始,而不是 db.get('tags') 在里面 generateTag 我提到的函数确实解决了这个问题,但仍然想知道是否有更好的方法。

    2 回复  |  直到 8 年前
        1
  •  0
  •   Alexander Tsepkov    8 年前

    对于其他感兴趣的人,这就是我如何使用 tagPromise 我在更新中提到的方法(如果PockDB专家有更好的答案,我会接受):

    var tagList = [ /* set of dictionary words to cycle through */ ];
    var tagPromise = db.get('tags');
    function generateTag(id, callback) {
        tagPromise = tagPromise.then(function() {
            return db.get('tags');
        }).then(function (tagData) {
            var tag = '', remainder = tagData.tagCount, quotient;
    
            while (remainder >= tagList.length) {
                quotient = Math.floor(remainder / tagList.length);
                tag += tagList[quotient - 1];
                remainder -= tagList.length * quotient;
            }
            tag += tagList[remainder];
            tag = tag.charAt(0).toLowerCase() + tag.slice(1);
    
            tagData.tagCount++;
            tagData.tags[tag] = id;
            callback(tag);
    
            return db.put(tagData);
        }).catch(function (err) {
            console.error(err);
        });
    }
    
    class Element {
        constructor() {
            var self = this;
            generateTag('element' + Date.now(), function (tag) {
                self.tag = tag;
            });
        }
    }
    
        2
  •  0
  •   Bernhard Gschwantner    8 年前

    我发现很难理解你想要实现的目标。你能发布标签文档以及元素和标签的示例吗?

    乍一看,获取和更新单个“标签”文档看起来很臭,我认为使用视图更有意义。但为了得到一个明智的回应,我需要更多的细节,请!谢谢