Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

274
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda