3 回答

TA貢獻1772條經驗 獲得超6個贊
有一種方法
在這里如何做:
使用交易
在您想要的路徑上讀取一個條目并鎖定您想要的路徑,條目是設備的 guid + 時間戳。
如果時間戳 < 比你的,路徑沒有鎖,你可以通過寫你的 guid 和你的時間戳 + 你需要鎖的時間來獲取它。
當交易成功時,你就是贏家,可以為所欲為。
完成后,寫入當前時間戳以釋放鎖

TA貢獻1865條經驗 獲得超7個贊
如果有人需要它,這就是我在特定路徑 3s 處構建和獲取一把鎖的方法。- 在每個表(路徑),您可以關聯一個包含此路徑鎖的 tableInfo。- 如果沒有其他人需要鎖,則獲取、釋放和延長時間。您可以使用嘗試獲取此鎖的其他設備的 guid 在另一個字段上添加偵聽器。并樂于釋放它而不是延長你的時間。
fbBase.child(tableInfoChildRef).child(TableInfo.Field.Lock.name).runTransaction(new Transaction.Handler() {
public Map<String, Object> lock(){
Map<String, Object> data = new ArrayMap<>();
data.put(TableInfo.Field.Lock.guid, AppGUID.get().toString());
data.put(TableInfo.Field.Lock.timestamp, System.currentTimeMillis()+3000);
return data;
}
@NonNull
@Override
public Transaction.Result doTransaction(@NonNull MutableData mutableData) {
if(mutableData.getValue() == null) {
mutableData.setValue(lock());
return Transaction.success(mutableData);
}else{
Long lockTimestamp = mutableData.child(TableInfo.Field.Lock.timestamp).getValue(Long.class);
if(lockTimestamp < System.currentTimeMillis()){
mutableData.setValue(lock());
return Transaction.success(mutableData);
}
}
return Transaction.abort();
}
@Override
public void onComplete(@Nullable DatabaseError databaseError, boolean b, @Nullable DataSnapshot dataSnapshot) {
if(b) LogDelay.send("WIN");
else LogDelay.send("LOSE");
}
});

TA貢獻1833條經驗 獲得超4個贊
Realtime Database 和 Cloud Firestore 都沒有一種機制可以讓您在處理數據庫時強制鎖定整個數據庫,甚至只是鎖定其中的一部分任意時間。像這樣的東西在現實世界中根本無法擴展。
兩個數據庫都提供事務機制,這是唯一以原子方式和一致地執行讀寫的方法。如果您對某些其他形式的鎖定有絕對的要求,那么云托管數據庫可能不是您的最佳選擇。要么,要么您通過您控制的單個中間件匯集所有訪問權限,這也不會很好地擴展。
添加回答
舉報