Firebase SDK for Java/Android を使用したマルチプレイヤー ゲームには、4 人のプレイヤーが一緒にプレイできるゲーム ルームがあります。
マッチメイキングを実装するために、プレイヤーが参加できるすべてのルームの Firebase リファレンスを用意しました。これらの参照にはそれぞれ、参加しているプレイヤーの UUID を含む 4 つのスロット (子ノードとして) があるか、スロットがまだ利用可能な場合は空の文字列があります。
2 人 (またはそれ以上) のプレイヤーが同時に同じスロットを要求するのを防ぐために、トランザクションを使用しています。次のコードはその目的に適していますか?
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
ますか? どちらの場合も、トランザクションが完了した後、書きたかった値がそこにないということですが、これは正しいですか?