我使用 Firebase SDK for Java/Android 的多人游戏有游戏室,可以让 4 名玩家一起玩。
为了实现匹配,我为玩家可以加入的每个房间都有一个 Firebase 参考。这些引用中的每一个都有 4 个插槽(作为子节点),其中包含正在参与的玩家的 UUID,如果插槽仍然可用,则为空字符串。
为了防止两个(或更多)玩家同时占用同一个位置,我正在使用交易。以下代码是否适用于此目的?
private int mUserSlot;
firebaseReference.runTransaction(new Transaction.Handler() {
@Override
public Result doTransaction(MutableData currentData) {
for (int s = 0; s <= 3; s++) { // loop through all slots
final String slotValue = currentData.child(slotFromLocalID(s)).getValue(String.class);
if (slotValue == null || slotValue.equals("") || slotValue.equals(mUserUUID)) { // if slot is still available
currentData.child(slotFromLocalID(s)).setValue(mUserUUID);
mUserSlot = s;
return Transaction.success(currentData);
}
}
return Transaction.abort();
}
@Override
public void onComplete(FirebaseError error, boolean committed, DataSnapshot currentData) {
if (error == null) {
if (committed) {
System.out.println("User is now in slot "+mUserSlot);
}
else {
System.out.println("User could not join, all slots occupied");
}
}
else {
System.out.println("Error: "+error.getMessage());
}
}
});
但是,我在上面Exception
的error != null
分支中抛出一个onComplete()
进行调试,经过一些测试运行后,我可以看到以下错误消息(来自error.getMessage()
我的调试日志:
The transaction was overridden by a subsequent set
这到底是什么意思?我认为这些事务是为了防止同时访问相互覆盖的相同字段。这是否意味着应用程序的某些其他部分正在写入该字段而没有事务?
在这种情况下,我可以像处理它一样处理它!committed
吗?这意味着,在这两种情况下,交易完成后我想要写入的值都不存在,这是正确的吗?