Как я могу отменить транзакцию после прочтения документов? - PullRequest
1 голос
/ 01 мая 2020

Я пытаюсь создать игру, в которой удаляю баланс 2 пользователей одновременно, только если у них там достаточно золота. Как только я получу все документы (пользовательские балансы), я делаю некоторую логи c и проверяю, что новый баланс не будет <0: </p>

const removeGamglingBalanceFor2Users = (
    user1, user2, amount, resolve, reject,
) => {
  const userDocRef1 = db.collection(DB_USERS).doc(user1.id);
  const userDocRef2 = db.collection(DB_USERS).doc(user2.id);
  db.runTransaction(
      (t) => t.getAll(userDocRef1, userDocRef2).then((docs) => {
        const balances = [];
        docs.forEach((doc) => {
          balances.push(doc.data()[FIELD_BALANCE] - amount);
        });

        if (Math.min(...balances) < 0){
          reject(INSUFFICIENT_FUNDS);
          t.rollback();
          return;
        }

        [userDocRef1, userDocRef2].forEach((doc) => {
          t.update(doc,
              { [FIELD_BALANCE]: FieldValue.increment(-amount) });
        });
      }),
  ).then(() => {
    resolve();
  }).catch((err) => {
    reject(err);
  });
};

Этот код выполняет на стороне сервера SDK администратора и служебная учетная запись.

Даже если условие Math.min(...balances) < 0) выполнено, оно отклоняет обещание, но не попадает в блок отклонения. Кроме того, он продолжает работать и удаляет баланс.

Вместо t.rollback() Я попытался t.abort(), но это не известно как функция ..

  • Есть ли способ остановить транзакцию?
  • Это хороший способ удалить сальдо из транзакций?

1 Ответ

1 голос
/ 01 мая 2020

Попробуйте использовать throw INSUFFICIENT_FUNDS вместо reject(INSUFFICIENT_FUNDS)

const removeGamglingBalanceFor2Users = (
    user1, user2, amount, resolve, reject,
) => {
  const userDocRef1 = db.collection(DB_USERS).doc(user1.id);
  const userDocRef2 = db.collection(DB_USERS).doc(user2.id);
  db.runTransaction(
      (t) => t.getAll(userDocRef1, userDocRef2).then((docs) => {
        const balances = docs.map(doc => doc.data()[FIELD_BALANCE] - amount)
        
        if (Math.min(...balances) < 0)
          throw INSUFFICIENT_FUNDS

        [userDocRef1, userDocRef2].forEach((doc) => {
          t.update(doc,
              { [FIELD_BALANCE]: FieldValue.increment(-amount) });
        });
      })
  )
  .then(() => resolve())
  .catch(reject);
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...