拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 如何避免两个用户同时按下底部的重复栏位计数器

如何避免两个用户同时按下底部的重复栏位计数器

白鹭 - 2022-01-25 1952 0 0

我有一个包含整个用户产品的集合,并且为了避免阅读所有档案以获得集合的长度,我在创建档案后为每个栏位增加一个值 1,好的,现在一切正常

在这里,我使用这种方法来判断档案是否存在,这样我可以避免在离线模式下重复计数器

 removeProduct1(){
    FirebaseFirestore.instance.collection("product").doc('product1')
        .get(const GetOptions(source: Source.server)).then((value1) {
      if(value1.exists) {
        FirebaseFirestore.instance.collection("product").doc('product1').delete();
        FirebaseFirestore.instance.collection("product").doc('productCount').update({
          'productCount': FieldValue.increment(-1),
        });
      }
    }).onError((error, stackTrace) {
      ScaffoldMessenger.of(context).showSnackBar(snackBar,);
      });
  }

也一切正常,但我注意到如果两个用户同时按下此方法的按钮,那么它会减少两个值 -2 也许有人会认为当两个用户同时按下按钮时它很少,嗯,这是只是我真正拥有的简单示例,我的页面包含太多用户,这对于两个用户点击按钮并不罕见

编辑 MOER 解释

我有一个名为的集合Friends,其中包含朋友的用户 ID,例如 user1 他的 id 是ABC,user2 他的 id 是所以 id通过关注DEF 变成最终的Friends collection这样的, 并且接下来的每一个都增加计数器 1ABCDEFfunctionfunction

makeFriends(){
  // here i make sure first if the friends Ids are not exists To avoid suspiciously increasing the counter in offline mode and its work very well 
  

    FirebaseFirestore.instance.collection("Friends").doc(user1Id user2Id).get().then((value) {
        if(!value.exists){
          // here to add ids to the friends collection 
          FirebaseFirestore.instance.collection("Friends").doc(user1Id user2Id).set({
            'test':''
          });
          //here to increase counter in other colection which is users for both user 
          //user1
      FirebaseFirestore.instance.collection("users").doc(user1Id).update({
        'friendsCounter':FieldValue.increment(1)
      });
      //user2
      FirebaseFirestore.instance.collection("users").doc(user2Id).update({
        'friendsCounter':FieldValue.increment(1)
      });
    }
  });
}
 

好的,现在一切顺利,他们成为了朋友,价值增加了??,他们的 ID 成为朋友收藏的单位 .. 这里的图片可以更好地解释

图 1

图片

在这里,我有function责任洗掉FriendsCount Field他们两个都减少一个值的朋友

deleteFriends(){
  // here i make sure first if the friends Ids are exists To 
  // avoid suspiciously decrease the counter in offline mode and its work very well
  FirebaseFirestore.instance.collection("Friends").doc(user1Id user2Id).get().then((value) {
    if(value.exists){
      // here to remove ids from the friends collection
      FirebaseFirestore.instance.collection("Friends").doc(user1Id user2Id).delete();
      //here to decrease counter for both user
      //user1
      FirebaseFirestore.instance.collection("users").doc(user1Id).update({
        'friendsCounter':FieldValue.increment(-1)
      });
      //user2
      FirebaseFirestore.instance.collection("users").doc(user2Id).update({
        'friendsCounter':FieldValue.increment(-1)
      });
    }
  });
}

ok now also everything going fine .. lets say user1 deleted his friend user 2 , by the previous functionthe Friends id which is ABCDEFhas been deleted so next time if user 2 want to do the same opretion it will fail because Friends ids are not exist anymore ..

the problem IS : lets say these two users are still friends and these two user visited each others profiles and hit the button at the same time which is call the pervious function (deleteFriend) so they gonna get the same return value which is (yes exists) then will be double decrease value for both of them instead of one as required .

means if their friendsCount was 1 both of them when they was a friend so tee value will be -1 instead 0 because there two operation was proceed

and this happen only if these two user hit the button at the same moment , but if the user 1 hit the button before user 2 then user 2 want to do same operation so he ganna fail because friendId was deleted by user1 operation as a condition statement in previous function ..

if(value.exists) i thought it too fast to delete friendIds before it give same result to other user if they together call the function at the same time   

of course i can prevent the button of calling the delete function in case one of these user is already deleted other but I didn't see this as a strong solution since i can't grantee traffic jam or any reason else like bad users behavior .. etc , also basically i can't do it because delete button must be available as long as they still a friends

Note: this also happen in addFriends buttom call too if two users hit it at the same time , double value 2 instead one ..

如果有两个用户同时查询相同的档案,或者任何好的解决方案,我需要任何方法来避免服务器给出相同的结果

uj5u.com热心网友回复:

如果您需要读取和写入档案来更新它,您应该使用事务来防止当多个用户几乎同时执行操作时出现的竞争条件。

在这里你肯定要使用事务,因为如果洗掉由于某种原因失败,减量操作也应该失败(反之亦然)。

FlutterFire 关于事务的档案也有很好的解释和示例代码以供入门。

标签:

0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *