2016-09-20 35 views
1

我正在运行一个事务来更新我的对象的likeCount。每个styleId参数都保证是唯一的。当我喜欢这些物体的速度有点快时,我得到一个Firebase Database error: The transaction was overridden by a subsequent set事务被后续设置覆盖

public class LikeCountTransaction { 

    public static final String PATH = "styles/%s/likeInfo"; 
    private final DatabaseReference databaseReference; 

    @Inject public LikeCountTransaction(DatabaseReference databaseReference) { 
     this.databaseReference = databaseReference; 
    } 

    public void execute(Long styleId) { 
     databaseReference.child(String.format(PATH, styleId)).runTransaction(new Transaction.Handler() { 
      @Override public Transaction.Result doTransaction(MutableData mutableData) { 
       MutableData likeCount = mutableData.child("likeCount"); 
       Long likeCountValue = likeCount.getValue(Long.class); 
       if (likeCountValue != null) { 
        likeCount.setValue(likeCountValue + 1); 
        mutableData.child("likeModified").setValue(ServerValue.TIMESTAMP); 
        return Transaction.success(mutableData); 
       } else { 
        return Transaction.success(mutableData); 
       } 
      } 

      @Override public void onComplete(DatabaseError databaseError, boolean committed, DataSnapshot snapshot) { 
       if (committed) { 
        List<String> filterPaths = snapshot.child("filters").getValue(new GenericTypeIndicator<List<String>>() { 
        }); 
        Long likeCount = snapshot.child("likeCount").getValue(Long.class); 
        Long likeModified = snapshot.child("likeModified").getValue(Long.class); 
        Map<String, Object> payload = new HashMap<>(); 
        for (String path : filterPaths) { 
         payload.put(path.concat("/likeCount"), likeCount); 
         payload.put(path.concat("/likeModified"), likeModified); 
        } 
        databaseReference.updateChildren(payload); 
       } else { 
        if (databaseError != null) 
         Timber.e(databaseError.toException(), databaseError.getMessage()); 
       } 
      } 
     }); 
    } 
} 
+0

您使用的是哪个版本的Firebase? –

+0

@qbix验证和数据库:9.4.0 –

+0

我能够重现错误,但不一致。你在每次测试中都得到它吗? –

回答

1

根据我的实验与您发布的代码,我相当肯定,问题是这种说法引起:

databaseReference.updateChildren(payload); 

虽然此更新不会修改任何修改的同一孩子的doTransaction(),它正在修改相同的父位置,databaseReference。显然,Firebase交易处理会将任何孩子的更新视为对位置的修改,从而使交易无效。

要确认这一点,请注释掉updateChildren()声明并运行测试。当我这样做时,错误没有发生。

+0

我在最接近的通用父引用上进行多路径更新,而不是在数据库的根引用上进行多路径更新,这已解决了问题 –