对于以下数据库示例结构:
{
"stats": {
"posts_count": 231,
"posts_by_category": {
"sports": {
"count": 12,
"foo": "bar"
}
},
"posts_by_language": {
"english": {
"count": 12,
"foo": "bar"
}
}
}
}
在[英语,体育]类别中有一篇新帖子,如何进行以下更改来进行交易:
stats/posts_count +1
stats/posts_by_category/sports/count +1
stats/posts_by_language/english/count +1
基本上我不知道如何导航/编辑MutableData对象以反映更改,并且我想要一个示例(最好不使用DAO类)
db.getReference("stats").runTransaction(object : Transaction.Handler {
override fun doTransaction(currentData: MutableData): Transaction.Result {
????
return Transaction.success(currentData)
}
override fun onComplete(
error: DatabaseError?,
committed: Boolean,
currentData: DataSnapshot?
) {
}
})
谢谢
答案 0 :(得分:0)
事务在单个节点上运行。因此,如果要以事务方式更新数据库中的多个分支,则必须在最低的公共祖先节点上运行单个事务。在您的示例中,该名称为stats
。请注意,这可能在写操作上引起很多争用。如果stats
节点可能由许多客户端在同一时间更新,则可能导致许多重试,并且可能导致事件失败。
但是在您的示例中,您似乎想增加计数器,自今年早些时候以来,Firebase Realtime Database作为本机操作支持该计数器。因此,我没有在stats
上运行事务,而是在其上运行以下更新操作:
Map<String, Object> updates = new HashMap<>();
updates.put("posts_count", ServerValue.increment(1));
updates.put("posts_by_category/sports/count", ServerValue.increment(1));
updates.put("posts_by_language/english/count", ServerValue.increment(1));
db.getReference("stats").updateChildren(updates);
这里要注意的事情:
/
是一种特殊的表示法,它允许更新嵌套属性。ServerValue.increment(1)
作为标记发送到数据库,然后由数据库自动执行。