Skip to content

Concurrent updates that don't interfere with each other #4224

@nikgraf

Description

@nikgraf

Problem

I need to get the first entry of a list of oneTimeKeys for a specific user and update it to be connected to the user that “claims” it.

What I did until now:

const oneTimeKeyResult = await prisma.oneTimeKey.findMany({ // could be findFirst
  where: {
    user: { id: userId },
    claimedByUserId: { equals: null },
  },
  take: 1,
});
const oneTimeKey = await prisma.oneTimeKey.update({
  where: { id: oneTimeKeyResult[0].id },
  data: {
    claimedByUser: { connect: { id: currentUser.id } },
  },
});

The problem here is that if two or more users try to claim the same oneTimeKey at the same time they can can and it actually happens sometimes in production.

Suggested solution

Running the find and update in a transaction would be nice, but this is not supported currently.

Alternatives

Since I'm running on Postgres (if I understand correctly) I could do a executeRaw with an update using FOR UPDATE SKIP LOCKED

https://stackoverflow.com/a/56441907/837709
https://dba.stackexchange.com/questions/69471/postgres-update-limit-1

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions