短版:
在Firebase事务中(在Java中),如果我从MutableData.getValue()
获得意外或不一致(陈旧)的值,我应该如何进行错误检查并确保在必要时重复运行事务?我何时使用Transaction.abort()
vs Transaction.success()
?
长版:
我想用Java编写一个Firebase事务
检查值“foo”是否存储在某个位置,如果不同或缺少则记录错误,然后
将值更新为“bar”。
我们希望“foo”位于该位置,因为它在运行事务之前已由同一客户端成功编写。
请考虑以下事项:
public Transaction.Result doTransaction(MutableData data) {
String value = (String) data.getValue();
if(value == null || !Transaction.equals("foo")) {
return Transaction.abort();
}
data.setValue("bar");
return Transaction.success(data);
}
我知道data.getValue()
可能会返回陈旧的值(包括null
),因为Firebase的最终一致性,因此事务可能需要多次执行。但是,如果我在Transaction.abort()
语句中返回if
,那么事务似乎只运行一次。如果我用Transaction.success(data)
替换它,我不会犯下错误的值吗?如何检测值实际上是否为空“foo”?
答案 0 :(得分:3)
(自我回答;必要时更正!)
通过实验,我发现如果我想让交易再次运行,我需要使用Transaction.success(...)
。 Transaction.abort()
始终阻止Firebase再次尝试,因此我应该在我确定无法继续进行交易时使用它。 (例如,如果data.getValue()
表示数据位置处的某些内容已关闭,并且任何待处理的内容都无法更正。)在我的示例中,data.getValue() == null
似乎是abort()
的一个特别糟糕的情况因为早期写入可能有新的值待定。
如果我在错误情况下返回Transaction.success(data)
,Firebase将确保最终的一致性。例如我不会意外地将null
写到该位置,除非data.getValue()
给出的值确实丢失。
我可以使用Transaction.Handler.onComplete(...)
方法执行所有错误检查,该方法有DataSnapshot
参数来检查该位置的最终数据。