FireStore交易:交易不是原子的

时间:2018-07-01 14:19:39

标签: javascript firebase google-cloud-firestore firebase-admin

我试图在一个路径上设置一些数据,然后在较早的设置操作成功后尝试从另一路径删除数据。对于我正在使用FireStore交易。以下是代码。

const unapprovedItemRef = admin
  .firestore()
  .collection("unapproved")
  .doc(id);

return admin.firestore().runTransaction(transaction =>
  transaction
    .get(unapprovedItemRef)
    .then(unapprovedItemSnapshot => {
      const item = unapprovedItemSnapshot.data();
      if (!item) {
        throw new Error("No such item");
      }

      const data = {
        added_on: new Date()
      };

      const dataRef = admin
        .firestore()
        .collection("data")
        .doc('saved');

      return transaction.set(dataRef, data);
    })
    .then(() => transaction.delete(unapprovedRef)) // deliberate error
    .then(() =>
      res.status(200).send({
        message: "Success"
      })
    )
    .catch(err =>
      res.status(200).send({
        message: "Failed",
        error: err.message
      })
    )

问题是,delete操作失败(因为我故意在其中引入了一个错误),但是set操作仍然成功,但它也应该失败,因为它只有一半逻辑事务。

我在这里做什么错了?

1 个答案:

答案 0 :(得分:0)

由于您附加了自己的.catch块,因此Firestore不知道您的交易失败。您的catch块会将throw new Error("No such item")转换为成功的Promise,Firestore会使用该Promise提交您的交易。

此外,transaction.delete()行从未执行过,因为前一个块失败了。如果将这条线移动到catch块之后,它也会导致事务失败。