发生错误时如何中止 Firestore 事务
Posted
技术标签:
【中文标题】发生错误时如何中止 Firestore 事务【英文标题】:How to abort a Firestore transaction in case of error 【发布时间】:2019-01-29 17:04:06 【问题描述】:我在 https 云函数(运行 Express)中使用 Firestore runTransaction
方法。
我想要的是确保如果任何读取或写入失败,其他事务读取或写入将不会运行或在需要时回滚。
交易
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
in 参数。
添加艺术作品标签
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
非常感谢
PS:我认为我滥用了事务......我应该做的可能只是使用顺序承诺而不是 Promise.all,对吧?
【问题讨论】:
【参考方案1】:API documentation for runTransaction 声明:
如果事务成功完成或被明确中止 (通过 updateFunction 返回一个失败的 Promise),Promise updateFunction 返回的将在此处返回。否则,如果 交易失败,一个被拒绝的 Promise 和相应的失败 将返回错误。
您所要做的就是正确地返回一个被拒绝的承诺。您在该事务中做了什么并不重要 - 所有这些都将被回滚。
【讨论】:
就是这样。谢谢【参考方案2】:我不确定runTransaction
要使您的函数和查询更稳定,您应该多次使用以下命令来阻止整个脚本崩溃。
try
//some code
catch (e)
//put code here to flag up issues with runTransaction
console.error("Oh No, Not Again said the PlantPot", e);
https://firebase.google.com/docs/database/admin/save-data
【讨论】:
以上是关于发生错误时如何中止 Firestore 事务的主要内容,如果未能解决你的问题,请参考以下文章