我们知道,火力地堡没有一个计数查询,有一个计数器的方法有两种,得到所有数据在客户端或存储在数据库中的计数值。我使用第二种方法,因为第一种方法只有在数据很少时才有效。火力地堡计数器,增量更新的情况下
这种方法的问题是,我可以有很多并发的作家,我用我的方法解决了这个问题,如果数据未被存储,它会尝试用增加或减少的计数器来重新保存数据。
确定当我只想更改一个计数器时,此方法运行良好,但在不同的情况下,我想用一个事务更改许多不同的计数器,并且在此模式下存在一种风险,即经过不同的尝试后数据无法保存,因为我们可以在许多不同的节点中拥有许多并发写入器。与原子更新数据结构的一个例子是如下:
如果我保存这个
"comment": {
"counter": {},
"Data": {
"$Comment":{}
}
}
comment/counter = val + 1
comment/Data/comment1 = data
它的工作原理,如果我不更新,因为其他作家正在更新计数器就在我可以用一个新的重试计数器的值,通常第一次后,我得出结论:成功的操作,但举例来说,如果我想删除一个用户,他的一切行动,我想存储这种类型的数据
"comment":{
"counter":{},
"Data": {
"$Comment":{}
}
},
"$user": {
"follower":{
"counter":{},
"data":{
"$Follower": {}
}
}
}
comment/counter = val - 1
comment/Data/comment2 = null
user1/follower/counter = val - 1
user1/follower/data/user30 = null
user2/follower/counter = val - 1
user2/follower/data/user30 = null
user3/follower/counter = val - 1
user3/follower/data/user30 = null
是可见的,在大批量更新的情况下,我必须更新很多计数器t可以有很多并发编写器,在这种情况下,很容易在不同的重试之后无法更新所有计数器。
另一种情况是这样的
"photo":{
"$photo":{
"comment":{
"counter":{},
"Data": {
"$Comment":{}
}
}
}
photo/10/comment/counter = val - 1
photo/10/comment/Data/comment1 = null
photo/10/comment/counter = val - 1
photo/10/comment/Data/comment2 = null
photo/10/comment/counter = val - 1
photo/10/comment/Data/comment3 = null
在这种情况下,这是不可能的,因为我尝试删除具有相同的计数器不同意见,可以是仅值+ 1或价值相等更新计数器 - 1 。如果我想删除所有的用户数据,他可能会在同一张照片上写下一些评论,但是我不能删除一个交易中的所有评论,因为只有单笔交易才能更新计数器。
我看到很多这样的并发症,只是因为不存在存在于任何类型的数据库(SQL或NoSQL的)的计数查询。我不懂为什么。这涉及到很多问题,否则无解浪费时间
下面是我的javascript函数来更新计数器。它如果不能在该记得自己是一个递归函数,因为其他的更新并发作家
this.singleUpdate = function (paths, increment, countPath, retryCounter, callback) {
firebase.database().ref(countPath).once('value', function (counter) {
var value = counter.val() ? counter.val().value : 0;
var countValue = increment ? value + 1 : value - 1;
paths[countPath] = { value: null };
if (!increment && countValue == 0) { paths[countPath] = null; }
else {
paths[countPath].value = countValue;
}
firebase.database().ref().update(paths, function (error) {
if (error) {
retryCounter++;
if (retryCounter < 3) { singleUpdate(paths, increment, countPath, retryCounter, callback); }
else { callback(false, error); }
} else {
return callback(true, countValue);
}
});
});
}
这是一个问题?如果是这样,您是否可以提供演示此问题的代码示例以及Firebase结构的片段(如文本请勿插入图片),以便我们了解您的数据? – Jay
我发布我的函数来更新计数器,但问题不在于客户端代码,而是在Firebase数据结构中,如果我想更新一些不同的计数器,可能我因为更多计数器意味着更多可能的并发编写者而导致我的事务失败。但在firebase不存在一个计数查询这是唯一的方法可能我认为 – DThink