我有一個包含整個用戶產品的集合,并且為了避免閱讀所有檔案以獲得集合的長度,我在創建檔案后為每個欄位增加一個值 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 關于事務的檔案也有很好的解釋和示例代碼以供入門。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/415694.html
標籤:
上一篇:在代理傳遞中使用變數時,NginxTooManyRedirects,直接傳遞值時作業正常
下一篇:在matplotlib中疊加imshow和scatter時,set_position和set_size_inches無法正常作業
