1

我使用 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());
        }
    }

});

但是,我在上面Exceptionerror != null分支中抛出一个onComplete()进行调试,经过一些测试运行后,我可以看到以下错误消息(来自error.getMessage()我的调试日志:

The transaction was overridden by a subsequent set

这到底是什么意思?我认为这些事务是为了防止同时访问相互覆盖的相同字段。这是否意味着应用程序的某些其他部分正在写入该字段而没有事务?

在这种情况下,我可以像处理它一样处理它!committed吗?这意味着,在这两种情况下,交易完成后我想要写入的值都不存在,这是正确的吗?

4

1 回答 1

3

是的,该消息意味着您的一个客户正在写入同一位置,set而不是使用transaction哪个中止事务。我强烈建议不要在使用set交易的位置使用。

于 2013-09-03T21:04:43.307 回答