The simple code below is freezing.
To reproduce, just replace this.firestoreProvider
with admin.initializeApp().firestore()
console.log('Init the cat')
const kittyRef = this.firestoreProvider
.fs
.collection('cats')
.doc('kitty')
await kittyRef.set({
name: 'Kitty',
age: 85,
feedCount: 0,
})
console.log('Feeding the cat')
await this.firestoreProvider.fs.runTransaction(async transaction => {
const snapshot = await transaction.get(kittyRef);
const cat = snapshot.data()
if(cat.isDead) return
if(cat.age > 84) {
cat.isDead = true
await kittyRef.set(cat); // this need be written to the db
throw new Error('Kitty is dead')
}
cat.feeCount ++
await transaction.set(kittyRef, cat)
}, {maxAttempts: 5})
console.log('success')
I also discovered that once you run this code, it freezes but it also freezes every client that tries to read the kittyRef
for about 1 minutes.
It is not entirely clear what you are trying to do, but you have at least 2 problems:
You shouldn't be directly calling set()
on kittyRef
inside the transaction -- you've locked the object by reading it inside that transaction. You need to do that with a transaction.set()
call. This is why you are getting a hang.
Throwing an (unhandled) exception inside the transaction is going to cause it to abort as it will cause the updateFunction
to return a failed promise). More documentation here . The best answer here would be to pass information out of the transaction function and handle it once the transaction is over.
So, this code will run and complete and leave the cat marked as dead, but it won't throw the error. It should be enough to get you started though:
console.log('Init the cat')
const kittyRef = admin.firestore()
.collection('cats')
.doc('kitty')
await kittyRef.set({
name: 'Kitty',
age: 85,
feedCount: 0,
})
console.log('Feeding the cat')
await admin.firestore().runTransaction(async transaction => {
const snapshot = await transaction.get(kittyRef);
const cat = snapshot.data()
if(cat.isDead) return
if(cat.age > 84) {
cat.isDead = true
await transaction.set(kittyRef, cat); // this need be written to the db
console.log('kitty now dead');
return;
}
cat.feeCount ++
await transaction.set(kittyRef, cat)
}, {maxAttempts: 5})
console.log('success')
Also, I note it appears you have a typo of feeCount
instead of feedCount
, but that is not related to your current question.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.