postgresql - Förhindra kapplöpningstillstånd vid låsning av rader


Så jag har en tabell som heter 'Ready' som lagrar S3-objektreferenser som är redo för bearbetning. I min applikation som använder dessa data och ändrar dem vill jag kunna hämta det senaste S3-objektet, om dess relevanta leverantör inte används eller låset på den leverantören har gått ut.

Min tabellstruktur ser ut så här:

nyckel (PK) | leverantör | tidsstämpel (skapadKl) | låst | utgång

Jag använder TypeORM för att skapa en TRANSAKTION, hämta den senaste (olåsta) objektreferensen och uppdatera alla andra kolumner med den leverantören så att de också blir låsta, så att vi inte av misstag använder två uppsättningar data från samma leverantör.

Min kod ser ut så här:

return getManager().transaction(async (entityManger) => {
    const firstReady = await entityManger
      .createQueryBuilder(Ready, 'ready')
      .setLock('pessimistic_write')
      .select()
      .orderBy('timestamp')
      .where('locked = false or exp < :now', { now: Date.now() })
      .getOne();
    if (!firstReady) return;
    await entityManger
      .createQueryBuilder(Ready, 'ready')
      .update()
      .set({ locked: true, exp: Date.now() + vars.PG.LOCK_EXP })
      .where('provider = :provider', { provider: firstReady.provider })
      .execute();
    logger.debug(`Acquired lock on ${firstReady.provider} and S3 object key ${firstReady.key}`);
    return firstReady.key;
  });

Jag är orolig för att om, av en slump, två konsumenter frågade två separata rader med samma leverantör nästan samtidigt, skulle jag få en tävlingssituation. Jag har övervägt att låsa hela tabellen när en konsument gör denna fråga, men jag undrar om det finns ett bättre sätt. Tack!