1

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ますか? どちらの場合も、トランザクションが完了した後、書きたかった値がそこにないということですが、これは正しいですか?

4

1 に答える 1