我正在运行一个事务来更新我的对象的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 :(得分:1)
根据我对您发布的代码的实验,我相当确定问题是由此声明引起的:
databaseReference.updateChildren(payload);
虽然此更新不会修改doTransaction()
中修改的任何相同子项,但它正在修改相同的父位置databaseReference
。显然,Firebase事务处理会将对任何子项的更新视为对位置的修改,从而使事务无效。
要确认这一点,请注释掉updateChildren()
语句并运行测试。当我这样做时,错误没有发生。