我的目标是做一个交易来删除一个用户和他的所有文档(用户和广告集)。
当我删除一个用户时,我想在广告集合中用“deleted”:true更新他的广告。
所以我写了如下代码:
/// Marks user as deleted
Future<void> storeMarkAsDeleted() async {
final fs = FirebaseFirestore.instance;
final writeBatch = fs.batch();
// = Open a transaction to perform both operations
return fs.runTransaction((t) async {
final user = await t.get(fs.collection(collectionName).doc(id));
/// Reads the ad document
final ads = await fs
.collection(collectionName)
.where("ownerId", isEqualTo: id)
.get();
// Mark user as deleted
t.update(user.reference, {
"deleted": true,
});
// Update all docs
for (final doc in ads.docs) {
writeBatch.update(doc.reference, {
"clearedForSale": false,
"deleted": true,
});
}
// unless commit is called, nothing happens.
writeBatch.commit();
});
}
字符串
但我不确定这是否是正确的做法。
1条答案
按热度按时间pod7payv1#
这肯定是不正确的。您应该知道,事务处理程序可以运行多次(在重新运行之前回滚任何更改),以便处理事务处理文档上的争用。在事务中运行批处理(或任何其他非事务查询)意味着它们可能会发生多次,从而导致读取或写入的文档比您预期的要多。
在事务内部,您应该只使用事务对象来读写文档。
我建议查看交易的文档,以了解它们的行为。