问题
I have the following Cloud Function and want to find out whether I should use batched writes or a transaction:
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()
I do require this operation to never fail, however, I do not see any case this would ever fail.
Is there any reason to use a transaction instead in this case?
Conversely, is there any reason not to use a transaction here?
回答1:
You are only writing to Firestore (and not reading), so at first sight, there is no need to use a transaction since "transactions are useful when you want to update a field's value based on its current value, or the value of some other field" (see doc), and you should use a Batched Write.
However, you should note that "each transaction or batch of writes can write to a maximum of 500 documents" (see same doc). Since you mention that your queries "potentially return hundreds of documents" you may encounter a problem here and have to write in several batches.
Other point: You say "I do require this operation to never fail, however, I do not see any case this would ever fail". You cannot be sure that it will never fail: as explained in the documentation, a Cloud Function "might exit prematurely due to an internal error" (see point below for more details). For example there might be problem of connectivity between the Cloud Function platform and the Firestore one and your batched write fails (independently of your code).
To fulfill this requirement (i.e. "I do require this operation to never fail") you should take advantage of the possibility to retry a background Cloud Function and of the fact that a batch of writes completes atomically. For background Cloud Functions retrying, see this doc which explains:
- Why this might happen ("On rare occasions, a function might exit prematurely due to an internal error, and by default the function might or might not be automatically retried"), and
- How to deal with this situation (in two words, enable retries and make your background Cloud Functions idempotent).
来源:https://stackoverflow.com/questions/56643115/batched-writes-or-transaction-in-cloud-functions