🌐
GitHub
github.com › prisma › prisma › issues › 17136
Row locking support in `find*()` queries (via `FOR UPDATE`) · Issue #17136 · prisma/prisma
January 4, 2023 - If we could avoid it by locking the row, that would be great. function deactivate() { const user = await prisma.$transaction(async tx => { const user = await tx.user.findUnique({ where: { id: user.id } }); if (user.status !== 'ACTIVE') { throw new Error('User not active ...'); } // some business processing (not long transaction) return tx.user.update({ where: { id: user.id } }, data: { status: 'DELETED' }); }); await doAfterCommitProcessing(user); }
Author   prisma
🌐
Medium
medium.com › @connect.hashblock › 10-prisma-transaction-patterns-that-avoid-deadlocks-4f52a174760b
10 Prisma Transaction Patterns That Avoid Deadlocks | by Hash Block | Medium
October 14, 2025 - Normalize the order of ids everywhere you update multiple rows. Keep the transaction body short; do parsing, auth, and remote calls outside. Prefer upsert + unique indexes to avoid read–then–write races. For queue workers, use FOR UPDATE SKIP LOCKED. Add retries with jitter for 40P01 / 40001 failures. Limit blast radius with timeouts, and consider advisory locks for cross-table invariants. Deadlocks aren’t a moral failing; they’re a coordination tax. Prisma gives us a great API, but the patterns above decide whether your service queues politely or snaps under pressure.
Discussions

Row update with DB Row Lock (SELECT FOR UPDATE)
Problem There's an entire class of DB mutations that can be affected by race conditions. An example is incrementing a value by one. So when updating a row, we need a way to acquire a DB row loc... More on github.com
🌐 github.com
9
March 24, 2020
node.js - Row level locking with Prisma and PostgreSQL - Stack Overflow
I’m building an anonymous chat app for learning purpose where users are matched based on gender preferences. The application allows users to go online and be matched with another online user if their More on stackoverflow.com
🌐 stackoverflow.com
postgresql - How to use Postgres / Prisma as a queue, preventing workers from selecting already selected rows - Stack Overflow
I'm using Prisma so I'm not sure of the underlying SQL in Postgres but I'm doing all of my calls inside a transaction and setting the transaction isolation level to 'Serialized', which correctly fails due to a write conflict. I've looked into 'ACCESS EXCLUSIVE' lock in Postgres but doesn't this lock the entire table rather than just the rows ... More on stackoverflow.com
🌐 stackoverflow.com
Allow for locking of the database.
Problem I need to be able to create a row in a table based on information of whether a similar row exists or not: Lock table for creation Check if similar row exists If similar row exists, create i... More on github.com
🌐 github.com
4
July 20, 2020
🌐
Answer Overflow
answeroverflow.com › m › 1299770877004746764
Row locking on prisma suggestions - Prisma
October 26, 2024 - Hi, I have been using Prisma to develop a text based game, this has been going very smooth. However I have been stumbling on some very big issues for concurrent updates on certain rows e.g. auction, withdraw, depositing, where my players can get under their balance if they click very fast, which results in a - balance and offcourse unwanted results. I was able to solve this with raw sql row locking, see picture.
🌐
GitHub
github.com › prisma › prisma › issues › 1918
Row update with DB Row Lock (SELECT FOR UPDATE) · Issue #1918 · prisma/prisma
March 24, 2020 - So when updating a row, we need a way to acquire a DB row lock to prevent these types of race conditions. I think this could be a good solution. If data is a function, then SELECT FOR UPDATE is used. await prisma.counter.update({where: {id: 1}, data: counter => ({value: counter.value + 1})}) Or accept the above arguments with a new API like prisma.count.updateWithLock() Reactions are currently unavailable ·
Author   prisma
🌐
Stack Overflow
stackoverflow.com › questions › 78962255 › row-level-locking-with-prisma-and-postgresql
node.js - Row level locking with Prisma and PostgreSQL - Stack Overflow
Change FOR UPDATE for a FOR UPDATE SKIP LOCKED and you should be good. The fact that you lock the row only makes concurrent requests wait for it to be released, but they still use that same record later. SKIP LOCKED will make them skip to a different one instead.
🌐
Prisma
prisma.io › home › transactions and batch queries › transactions and batch queries › transactions and batch queries › transactions and batch queries
Transactions and batch queries (Reference) | Prisma Documentation
December 22, 2022 - Avoiding locks in an application with a high number of concurrent requests makes the application more resilient to load and more scalable overall. Although locking is not inherently bad, locking in a high concurrency environment can lead to unintended consequences - even if you are locking individual rows, and only for a short amount of time.
🌐
Stack Overflow
stackoverflow.com › questions › 75827244 › how-to-use-postgres-prisma-as-a-queue-preventing-workers-from-selecting-alrea
postgresql - How to use Postgres / Prisma as a queue, preventing workers from selecting already selected rows - Stack Overflow
I'm using Prisma so I'm not sure of the underlying SQL in Postgres but I'm doing all of my calls inside a transaction and setting the transaction isolation level to 'Serialized', which correctly fails due to a write conflict. I've looked into 'ACCESS EXCLUSIVE' lock in Postgres but doesn't this lock the entire table rather than just the rows ...
🌐
GitHub
github.com › prisma › prisma › issues › 3088
Allow for locking of the database. · Issue #3088 · prisma/prisma
July 20, 2020 - I need to be able to lock the table such that steps 2 and 3 happen "atomically". i.e., if another request comes in to create that row, then there will be no race condition between the checks of these two requests. Ideally there would be a way to lock only creation based on some other criteria, but that seems to be outside of the scope. prisma.lock(MyTable) { |t| t.checkMyStuff() t.createMyStuff() } prisma.myTable.lock(|t| {}) prisma.atomic(|p| => { // do stuff with the atomic version of the prisma client }) I am open to anything else that would fix the core issue.
Author   prisma
🌐
GitHub
github.com › prisma › prisma › issues › 5983
Add support for row-level locking (via `FOR UPDATE SKIP LOCKED`) · Issue #5983 · prisma/prisma
March 4, 2021 - To ensure only a single worker is processing one job, I can use row-level locking.
Author   prisma
Find elsewhere
🌐
Medium
medium.com › @mgoku0707 › concurrency-control-in-node-js-and-prisma-managing-simultaneous-updates-56b9f17859e5
Concurrency Control in Node.js and Prisma: Managing Simultaneous Updates | by Gokul Mahendiran | Medium
March 7, 2024 - Hierarchy level of locks from high to low · Consider a scenario where a database table represents a model with various fields, and users can update these fields through API calls. Now, what happens when two or more users attempt to update the same row simultaneously? Without proper concurrency control, conflicting updates may lead to data inconsistencies or loss. Let’s delve into implementing concurrency control using Node.js and Prisma.
🌐
OneUptime
oneuptime.com › home › blog › how to implement optimistic locking with prisma in node.js
How to Implement Optimistic Locking with Prisma in Node.js
January 25, 2026 - sequenceDiagram participant User1 participant User2 participant Database User1->>Database: Read record (version=1) User2->>Database: Read record (version=1) User1->>Database: Update where version=1, set version=2 Database-->>User1: Success (1 row updated) User2->>Database: Update where version=1, set version=2 Database-->>User2: Failure (0 rows updated) User2->>Database: Retry: Read record (version=2) User2->>Database: Update where version=2, set version=3 Database-->>User2: Success · First, add a version field to your models that need optimistic locking. // prisma/schema.prisma generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } model Product { id String @id @default(uuid()) name String description String?
🌐
DEV Community
dev.to › zenstack › how-to-build-a-high-concurrency-ticket-booking-system-with-prisma-184n
How To Build a High-Concurrency Ticket Booking System With Prisma - DEV Community
June 12, 2025 - The most straightforward way to resolve this issue is to utilize the database lock. However, while locking is not inherently bad, it can lead to unintended consequences in high-concurrency environments, even if you are only locking individual rows for a short amount of time.
Top answer
1 of 2
1

I realized, that for your specific usecase you could also increment your incrementalReportNumber with an atomic number operation

This avoids the need for a stricter transaction isolation level, because you only run update queries and avoid all read queries:

 const report = await prisma.$transaction(async (prisma) => {
      const school = await prisma.school.update({
        where: { id: schoolId },
        data: {
          incrementalReportNumber: {
            // increment the report number here
            increment: 1,
          },
        },
      });

      const newReport = await prisma.report.create({
        data: {
          publicId: school.incrementalReportNumber,
          schoolId: school.id,
          name: reportName,
        },
      });

      return newReport;
    });
2 of 2
1

I think the issue here is with the transaction isolation level used by Prisma when running the query.

The default transaction isolation level in Postgres is "read committed", this is what Prisma uses and it does not prevent non-repeatable reads.

Non-Repeatable Reads

If you're not sure what non-repeatable reads are, I am adding a good explanation taken from here

"A non-repeatable read is one in which data read twice inside the same transaction cannot be guaranteed to contain the same value. Depending on the isolation level, another transaction could have nipped in and updated the value between the two reads.

Non-repeatable reads occur because at lower isolation levels reading data only locks the data for the duration of the read, rather than for the duration of the transaction"

In your case, the following race condition might be happening due to non-repeatable reads.

  1. Transaction B: Read school data with report number x and increment to x + 1.
  2. Transaction A: Read school data with report number x and increment to x + 1.
  3. Transaction B: Commit report number x + 1 to database.
  4. Transaction A: Attempt to create report with x+1 report number and fail.

Unfortunately, Prisma does not currently support changing the transaction isolation level. So, you might need to come to some other workaround for this issue (possibly even writing raw SQL code).

We have a feature request for exactly this and I would really urge you to comment your problem over there. That way it would help us track demand for this feature and incentivize adding it quickly.

🌐
Saigon Technology
saigontechnology.com › home › blog › database transaction and how to handle it in nodejs with prisma
Database Transaction And How To Handle It In NodeJS With Prisma
June 13, 2025 - This mechanism involves acquiring and releasing locks on database objects such as tables, rows, or columns to control access by concurrent transactions.
🌐
GitHub
github.com › prisma › prisma › issues › 4988
Optimistic Concurrency Control · Issue #4988 · prisma/prisma
May 19, 2019 - // Optimistic const scored = 2 prisma.$transaction([ prisma.user.update({ data: { numPoints: { decrement: scored } }, where: { id: 'loser-user-id' }, lockingPolicy: { optimistic: 'updatedAt' } ), prisma.user.update({ data: { numPoints: { increment: scored } }, where: { id: 'winner-user-id' }, lockingPolicy: { optimistic: 'updatedAt' } ) ]) // Pessimistic (used to proof the API design, not meant for implementation) const scored = 2 prisma.$transaction([ prisma.user.update({ data: { numPoints: { decrement: scored } }, where: { id: 'loser-user-id' }, lockingPolicy: { pessimistic: 'ROW' } ), prisma.user.update({ data: { numPoints: { increment: scored } }, where: { id: 'winner-user-id' }, pessimisticLock: { on: 'ROW' } ) ], { isolation: 'REPEATABLE READ' })
Author   prisma
🌐
GitHub
github.com › prisma › prisma › discussions › 19714
Does prisma.$transaction lock rows/always perform asynchronously? · prisma/prisma · Discussion #19714
I am using Prisma and MongoDB. I am working on preventing a case where if a function is run twice at exactly the same time, my constraints are ignored. Here is an example of my case: async function...
Author   prisma
🌐
Saigontechnology
careers.saigontechnology.com › blog-detail › database-transaction-and-how-to-handle-it-in-nodejs-with-prisma
Database Transaction and how to handle it in NodeJS with Prisma | Careers Saigon Technology
Let's take a look into one of the most fundamental concepts of databases. This article will show you the main concepts of transaction and how you can manage transactions in NodeJS with Prisma.