Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

275
Visualizações
Firebase - One transaction for 2 paths in real time database

I have a database with the following structure:

Structure of my database

Now two paintings can be rated against each other and the rating is then updated. But it can happen that one painting is rated mutliple times at the same time. Therefore i tried using a nested transaction (see below) to avoid race conditions:

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;
    });
}

Now this solution doesn't really work and I have read that it isn't the best approach to this problem. The only solution I found was running a transaction on the root of my database but I'm afraid that this would lead to a bottleneck and many of the launched transactions wouldn't even write to the database since transactions are only retried 25 times (or is my fear here unfounded?). Are there any other solutions to this problem?

about 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

Firebase Realtime Database transactions run against a single path in your database. There is currently no way to run a transaction against multiple path, so the common approach is to run the transaction against the lowest-level shared path (/paintings in your case).

This can indeed lead to more contention as you have more users performing concurrent transactions.


The only alternative I've used at times is to build my own transaction mechanism using:

  1. Multi-path updates, to perform both writes at the same time.
  2. Security rules, to only allow the transition that make sense in my use-case.
  3. Client-side retries, so that contention or outdated data are still handled correctly.

This is fairly non-trivial even for simple cases, and may require changing your data structure and/or adding additional values to each request. But if you get past those hurdles, it will allow you to run a "transaction" across multiple paths.

about 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda