【问题标题】:Firebase - One transaction for 2 paths in real time databaseFirebase - 实时数据库中 2 条路径的一项事务
【发布时间】:2022-01-23 15:33:07
【问题描述】:

我有一个结构如下的数据库:

现在可以对两幅画作进行评分,然后评分会更新。 但可能会发生一幅画同时被多次评级的情况。因此我尝试使用嵌套事务(见下文)来避免竞争条件:

function pictureClicked(picture) {
    const db = getDatabase();
    const leftRef = ref(db, '/paintings/' + generateDbName(currentLeft));
    const rightRef = ref(db, '/paintings/' + generateDbName(currentRight));
    const winnerLeft = (picture === 'left') ? 1 : 0;

    runTransaction(leftRef, (leftP) => {
        if (leftP) {
            runTransaction(rightRef, (rightP) => {
                if (rightP) {
                    // Calculation of the new rating for each painting (Elo System)
                    const tRatingLeft = Math.pow(10, leftP.rating / 400);
                    const tRatingRight = Math.pow(10, rightP.rating / 400);

                    const expectedLeft = tRatingLeft / (tRatingLeft + tRatingRight);
                    const expectedRight = tRatingRight / (tRatingLeft + tRatingRight);

                    // Setting new rating
                    leftP.rating = leftP.rating + 32 * (winnerLeft - expectedLeft);
                    rightP.rating = rightP.rating + 32 * ((1 - winnerLeft) - expectedRight);
                }
                return rightP;
            });
        }
        return leftP;
    });
}

现在这个解决方案并没有真正起作用,我已经读到它不是解决这个问题的最佳方法。我找到的唯一解决方案是在我的数据库的根目录上运行一个事务,但我担心这会导致瓶颈并且许多启动的事务甚至不会写入数据库,因为事务只重试了 25 次(或我在这里的恐惧是没有根据的吗?)。这个问题还有其他解决方案吗?

【问题讨论】:

    标签: javascript firebase firebase-realtime-database


    【解决方案1】:

    Firebase 实时数据库事务针对您数据库中的单个路径运行。目前没有办法针对多条路径运行事务,因此常见的方法是针对最低级别的共享路径(在您的情况下为/paintings)运行事务。

    这确实会导致更多的争用,因为您有更多的用户执行并发事务。


    我有时使用的唯一替代方法是使用以下方法构建自己的事务机制:

    1. 多路径更新,同时执行两个写入。
    2. 安全规则,只允许在我的用例中有意义的转换。
    3. 客户端重试,以便仍能正确处理争用或过期数据。

    即使对于简单的情况,这也是相当重要的,并且可能需要更改您的数据结构和/或为每个请求添加额外的值。但是,如果您克服了这些障碍,它将允许您跨多个路径运行“交易”。

    【讨论】:

      猜你喜欢
      • 2021-11-23
      • 1970-01-01
      • 2018-12-29
      • 2021-03-10
      • 2019-05-15
      • 2020-09-19
      • 1970-01-01
      • 2021-10-07
      • 2020-05-15
      相关资源
      最近更新 更多