首页 > 解决方案 > 云函数中的批量写入或事务?

问题描述

我有以下云函数,想知道我应该使用批量写入还是事务:

const firestore = admin.firestore()
// The following two queries potentially return hundreds of documents.
const queryA = firestore.collectionGroup('a').where('b', '==', 'c'),
  queryB = firestore.collection('b').where('b', '==', 'c')

const snapshotA = await queryA.get(), snapshotB = await queryB.get()
const batch = firestore.batch()
for (const documentSnapshot of snapshotA.docs.concat(snapshotB.docs)) {
  batch.update(documentSnapshot.ref, { 'b': 'd' })
}
return batch.commit()

我确实要求这个操作永远不会失败,但是,我没有看到任何情况下这会失败。

在这种情况下是否有任何理由使用事务
相反,这里有什么理由不使用事务吗?

标签: firebasegoogle-cloud-firestoregoogle-cloud-functions

解决方案


您只是在写入Firestore(而不是读取),因此乍一看,没有必要使用事务,因为“当您想要根据字段的当前值或其他值更新字段的值时,事务很有用字段”(请参阅​​ doc),您应该使用批量写入。

但是,您应该注意“每个事务或每批写入最多可以写入 500 个文档”(参见同一文档)。既然您提到您的查询“可能返回数百个文档”,您可能会在这里遇到问题并且必须分几批编写。


另一点:您说“我确实要求此操作永远不会失败,但是,我看不到任何情况下这会失败”。您不能确定它永远不会失败:如文档中所述,云函数“可能由于内部错误而过早退出”(有关更多详细信息,请参见下文)。例如,Cloud Function 平台和 Firestore 之间可能存在连接问题,并且您的批量写入失败(与您的代码无关)。

为了满足这个要求(即“我确实要求这个操作永远不会失败”),您应该利用重试后台云函数的可能性以及一批写入原子完成的事实。对于后台 Cloud Functions 重试,请参阅此文档,其中解释了:

  1. 为什么会发生这种情况(“在极少数情况下,函数可能会由于内部错误而过早退出,默认情况下该函数可能会或可能不会自动重试”),以及
  2. 如何处理这种情况(一句话,启用重试并使你的后台 Cloud Functions 具有幂等性)。

推荐阅读