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 都没有一种机制可以让您在处理数据库时强制锁定整个数据库,甚至只是锁定其中的一部分任意时间。像这样的东西在现实世界中根本无法扩展。
两个数据库都提供事务机制,这是唯一以原子方式和一致地执行读写的方法。如果您对某些其他形式的锁定有绝对的要求,那么云托管数据库可能不是您的最佳选择。要么,要么您通过您控制的单个中间件汇集所有访问权限,这也不会很好地扩展。
添加回答
举报