下面的简单代码是冻结的。
要重新生成,只需将this.FireStoreProvider
替换为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')
我还发现,一旦运行此代码,它就会冻结,但它也会冻结试图读取kittyref
的每个客户机大约1分钟。
不完全清楚你在尝试做什么,但你至少有两个问题:
>
您不应该在事务中直接调用kittyref
上的set()
--您已经通过在事务中读取对象来锁定该对象。 您需要使用transaction.set()
调用来完成此操作。 这就是为什么你会被吊死的原因。
在事务中引发(未处理的)异常将导致事务中止,因为它将导致updateFunction
返回失败的承诺)。此处提供更多文档。此处的最佳答案是将信息传递出事务函数,并在事务结束后对其进行处理。
因此,这段代码将运行并完成,并留下标记为死亡的cat,但它不会抛出错误。 不过,这应该足以让你开始:
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')
另外,我注意到您似乎有一个feecount
而不是feedcount
的错误,但这与您当前的问题无关。