【问题标题】:Multiple document reads in node js Firestore transaction在节点 js Firestore 事务中读取多个文档
【发布时间】:2018-10-25 07:25:15
【问题描述】:

我想执行需要使用这些文档的先前值更新两个文档的事务。

为了这个问题,我正在尝试将 100 个令牌从一个应用程序用户转移到另一个应用程序用户。这个操作必须是原子的以保持我的数据库的数据完整性,所以在服务器端我想使用admin.firestore().runTransaction

据我了解runTransaction 需要在执行写入之前执行所有读取,那么在更新数据之前如何读取两个用户的余额?

这是我目前所拥有的:

db = admin.firestore();
const user1Ref = db.collection('users').doc(user1Id);
const user2Ref = db.collection('users').doc(user2Id);
transaction = db.runTransaction(t => {
    return t.get(user1Ref).then(user1Snap => {
        const user1Balance = user1Snap.data().balance;
        // Somehow get the second user's balance (user2Balance)
        t.update(user1Ref , {balance: user1Balance - 100});
        t.update(user2Ref , {balance: user2Balance + 100});
        return Promise.resolve('Transferred 100 tokens from ' + user1Id + ' to ' + user2Id);
    });
}).then(result => {
    console.log('Transaction success', result);
});

【问题讨论】:

    标签: node.js firebase google-cloud-firestore firebase-admin


    【解决方案1】:

    【讨论】:

    • 这应该是选择的答案
    【解决方案2】:

    您可以使用Promise.all() 生成单个promise,该promise 在传递给它的数组中的所有promise 都已解析时解析。在所有文档读取完成后,使用该承诺继续工作 - 它将包含所有结果。你的代码的一般形式应该是这样的:

    const p1 = t.get(user1Ref)
    const p2 = t.get(user2Ref)
    const pAll = Promise.all([p1, p2])
    pAll.then(results => {
        snap1 = results[0]
        snap2 = results[1]
        // work with snap1 and snap2 here, make updates to refs...
    })
    

    【讨论】:

    • 谢谢!这会强制执行交易行为吗?寻找保护以防止 user1Refuser2Refthen().. 之前写入的情况。
    • 服务器强制执行事务行为,而不是客户端。客户必须遵守文档中所述的规则。使用我展示的表格,所有文档读取都将在文档写入之前发生,这是这里的重要要求。
    • 不,@DougStevenson,Dori 的意思是当 ref 在事务之外写入时会发生什么。
    • 这不会实现事务行为。
    • @hkchakladar 你仍然在交易内部使用这样的承诺,以确保观察到所有异步工作。
    猜你喜欢
    • 1970-01-01
    • 2018-05-11
    • 2019-07-20
    • 2017-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-24
    相关资源
    最近更新 更多