发生错误时如何中止Firestore交易 [英] How to abort a Firestore transaction in case of error

查看:37
本文介绍了发生错误时如何中止Firestore交易的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在https Cloud函数(运行Express)中使用Firestore runTransaction 方法.我想要的是确保如果任何读取或写入失败,则其他事务读取或写入将不会运行,或者在需要时将回滚.

I'm using Firestore runTransaction method in a https Cloud function (running Express). What I want is ensure that if any of the read or write fails the other transaction reads or writes won't run or will rollback if needed.

交易

admin.firestore().runTransaction(async (t) => {
  const { uid, artworkUid, tagLabel } = req.body;

  if (!tagLabel) {
    return Promise.reject('Missing parameters: "tagLabel"');
  }

  if (!artworkUid) {
    return Promise.reject('Missing parameters: "artworkUid"');
  }

  if (tagLabel.length < 3) {
    return Promise.reject('The tag must be at least 3 characters long');
  }

  const [ user, artwork ] = await Promise.all([
    getUser(uid),
    getArtwork(artworkUid)
  ]);

  return Promise.all([
    addArtworkTag({
      artwork,
      tagLabel,
      proposer: user
    }, t),
    giveXpFor({
      user,
      action: 'add-artwork-tags',
      type: user.can('add-artwork-tags') ? 'effective' : 'temporary'
    }, t)
  ])
})
.catch(err => res.status(403).send(err))
.then(() => res.status(200).send());

您会看到 addArtworkTag giveXpFor 函数将 t 用作参数.

As you can see the addArtworkTag and giveXpFor functions take the t in parameter.

addArtworkTag

export const addArtworkTag = function(params: { artwork: any, tagLabel: string, proposer: ShadraUser }, t?: FirebaseFirestore.Transaction): Promise<any> {
  const { artwork, tagLabel, proposer } = params;

  if (!artwork || !proposer || typeof tagLabel !== 'string') {
    return Promise.reject('Can\'t add the tag. Bad/missing datas');
  }

  const tag = <any>{
    slug: slugify(tagLabel),
    label: tagLabel,
    status: proposer.can('add-artwork-tags') ? 'validated' : 'proposed',
    proposerUid: proposer.uid
  };

  const tags = artwork.tags || [];
  tags.push(tag);

  const artworkRef = admin.firestore().doc(`artworks/${artwork.uid}`);

  t.set(artworkRef, { tags }, { merge: true });
  return Promise.resolve();
}

我的问题是:如果 addArtworkTag 函数失败(例如,由于参数错误),我如何中止(甚至回滚)事务,所以 giveXpFor 不会叫

My question is: If the addArtworkTag function fails (because of a bad parameter for instance) how can I abort (or even rollback) the transaction so giveXpFor is not called

非常感谢

PS:我认为我误用了交易...我应该做的可能只是使用顺序承诺而不是Promise.all,对吗?

PS: I think I've misused transactions... What I should do is probably just use sequential promises instead of Promise.all, right ?

推荐答案

runTransaction的API文档状态:

如果事务成功完成或被明确中止(通过updateFunction返回失败的Promise),PromiseupdateFunction返回的值将在此处返回.否则,如果交易失败,被拒绝的Promise以及相应的失败错误将被返回.

If the transaction completed successfully or was explicitly aborted (by the updateFunction returning a failed Promise), the Promise returned by the updateFunction will be returned here. Else if the transaction failed, a rejected Promise with the corresponding failure error will be returned.

要使交易正确失败,您要做的就是返回被拒绝的承诺.不管您在该交易中做了什么,都将被回滚.

All you have to do the fail a transaction correctly is return a rejected promise. It doesn't matter what you've done in that transaction - all of it will be rolled back.

这篇关于发生错误时如何中止Firestore交易的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆