如果以前在本地提交,Firebase事务不会远程中止

时间:2015-02-23 15:00:40

标签: android transactions firebase firebase-realtime-database

我正在构建一个Android应用,其中有几个用户可以访问,修改和删除相同的项目,而我正在使用Firebase来同步所有设备。 为了跟踪更新,项目具有时间戳。 我编写了一个事务,以便当我尝试删除该项时,它会检查我的副本的时间戳是否比远程副本旧:在这种情况下,事务中止并且项目不会被删除。

这是我的问题:

  1. 我的设备离线
  2. 我成功删除了该项
  3. 另一个用户修改远程数据库上的项目
  4. 我的设备上线并传播删除
  5. 我认为它会远程中止,因为远程时间戳更新。 如果我只能根据我的本地数据做出决定,我真的看不到中止功能的意义......

    我应该如何处理Firebase中的这类冲突?

    - 更新

    这是我用来删除项目的代码。如果其他用户在本地删除后远程更改了该项,则应该中止。

    private void removeItem(final ListItem item, final Firebase itemRef) {
        itemRef.runTransaction(new Transaction.Handler() {
            @Override
            public Transaction.Result doTransaction(MutableData mutableData) {
                if(mutableData == null) return Transaction.abort();
                else if((long)mutableData.child("lastUpdate").getValue() > item.getLastUpdate()) return Transaction.abort();
                else{
                    itemRef.removeValue();
                    return Transaction.success(mutableData);
                }
            }
        });
    

    请注意,我使用itemRef.removeValue()代替mutableData.setValue(null),因为第二个似乎不起作用。

2 个答案:

答案 0 :(得分:2)

Firebase最初在客户端应用事务,以提高并发性。如果该决定不符合您的用例,您可以将另一个参数传递给transaction方法,该方法告诉它绕过本地apply。

请参阅https://www.firebase.com/docs/web/api/firebase/transaction.html

  

applyLocally 布尔值可选

     

默认情况下,每次运行事务更新功能时都会引发事件。因此,如果它多次运行,您可能会看到中间状态。您可以将此值设置为false以禁止这些中间状态,而是等到事务完成后再引发事件。

答案 1 :(得分:1)

我用这种方式解决了我的问题:

  1. 我使用了mutableData.setValue(null),否则Firebase无法使交易正常运作
  2. 我明确地将applyLocally布尔值设置为true,因为我还需要查看本地事件
  3. 我不明白为什么mutableData.setValue(null)之前没有工作,我可能会错过以前的错误,但那就是问题所在。