提问者:小点点

为什么这个Firestore交易被冻结?


下面的简单代码是冻结的。

要重新生成,只需将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分钟。


共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的错误,但这与您当前的问题无关。