首页 > 解决方案 > 阅读文件后如何取消交易?

问题描述

我正在尝试构建一个游戏,只有当他们有足够的金币时,我才会同时删除 2 个用户的余额。一旦我得到所有文件(用户的余额),我正在做一些逻辑并检查新的余额不会小于 0:

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(),但它不被称为函数..

标签: javascriptfirebasegoogle-cloud-firestoretransactions

解决方案


尝试使用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);
};


推荐阅读