交易被后续集合覆盖

时间:2016-09-20 09:38:48

标签: android firebase firebase-realtime-database

我正在运行一个事务来更新我的对象的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());
                }
            }
        });
    }
}

1 个答案:

答案 0 :(得分:1)

根据我对您发布的代码的实验,我相当确定问题是由此声明引起的:

databaseReference.updateChildren(payload);

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

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

相关问题