Транзакция FireStore: транзакция не является атомарной - PullRequest
0 голосов
/ 01 июля 2018

Я пытаюсь установить некоторые данные по одному пути, а затем пытаюсь удалить данные из другого, как только предыдущая операция установки завершится успешно. Для я использую транзакции 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 голосов
/ 02 июля 2018

Поскольку вы прикрепили свой собственный блок .catch, Firestore не знает, что ваша транзакция не удалась. Ваш блок catch конвертирует throw new Error("No such item") в успешное Обещание, которое Firestore использует для фиксации вашей транзакции.

Кроме того, строка transaction.delete() никогда не выполняется, поскольку предыдущий блок завершился неудачно. Если вы переместите эту строку сразу после блока catch, это также приведет к сбою транзакции.

...