【发布时间】:2019-04-17 20:01:08
【问题描述】:
因此,我目前正在运行一些脚本来重置我们其中一款应用中的用户余额。我正在使用 firestore 来获取所有任务,然后根据我们每个用户的任务计算余额。听起来很简单吧?它应该是,它不是。问题是事务由于对同一文档的写入冲突而中止。发生这种情况是因为所有任务都同时传递给事务。
我尝试使用导致它们中止的 forEach 方法,因为它每次都在尝试更新相同的用户记录。 我已经尝试过(让任务任务),这给了我一个错误“无法迭代任务”。
async function updatestuff(){
console.log("start");
const tasksRef = db.collection('tasks');
try {
const allTasksSnapShot = await tasksRef.get();
allTasksSnapShot.forEach(async(doc) => {
//Run transaction for calculations for each task here
const tskUser = doc.data().taskUser;
const tuser = db.collection('backupusers').doc(tskUser);
if(doc.data().taskStatus == 'Not Completed'){
console.log('NOT');}
if(doc.data().taskStatus != 'Not Completed'){
console.log('Run transaction here and wait for it to finish?');
await db.runTransaction(async t => {
const userSnapShot = await t.get(tuser);
if (!userSnapShot) {return console.log('not a thing')}
//get new balance calculated
const newBalance = userSnapShot.actualbalance + doc.data().taskBalanceAdj;
await t.update(tuser, {actualbalance: newBalance});
})
}});
console.log("end")
}
catch (err) {
console.log('Error getting documents', err);
}
}
目前文档写入之间的冲突导致事务中途中止。
如果有人可以帮助我以异步方式将每个任务传递给事务,我将非常感激,等待事务完成然后传递下一个任务。 或者另一种可以获得相同结果的方法....
提前感谢你善良善良的灵魂!
【问题讨论】:
-
您将 async/await 与 then() 和 catch() 结合使用。这使得你很难推断你的代码在做什么,甚至可能是不正确的。如果您想使用 async/await,为什么不在整个代码中应用它以保持一致性和可读性?
-
你好,Doug,信不信由你,我已经看了你很久了,你的 Firecast 很棒!我更新了我的代码以删除 then catch 但是这让我意识到我可能需要重新访问这些视频和其他一些关于异步等待的示例。
-
那么这里的错误到底是什么?
-
所以当我运行它时,我得到“UnhandledPromiseRejectionWarning:错误:10 ABORTED:引用的事务已过期或不再有效。”大约一分钟后,功能停止。许多事务在前 30 秒内顺利完成。最后我得到一个错误,这些记录有太多争用,请再试一次,函数中止。所以我认为问题是由于任务被同步传递给事务,并且多次写入同一个文档,事务被中止。
标签: javascript transactions async-await google-cloud-firestore