🌐
Prisma
prisma.io › dataguide › postgresql › inserting-and-modifying-data › using-transactions
Using Transactions | Inserting and modifying data | PostgreSQL
Within a transaction, the executed statements can only affect the environment within the transaction itself. From inside the transaction, statements can modify data and the results are immediately visible. From the outside, no changes are made until the transaction is committed, at which time all of the actions within the transaction become visible at once.
Discussions

Manual transaction commit, rollback
Problem Since Prisma does not offer manual transaction rollbacks which is one of the reason TypeORM is preferred by users over Prisma. I intended to perform an E2E test on the production database, ... More on github.com
🌐 github.com
5
December 7, 2023
typescript - Using Prisma and transactions? - Stack Overflow
And the update either commits or rolls back depending on the last two lines. However, when I use the same "begin" and "rollback" but with Prisma-statements in between, they always stick regardless if I call rollback afterwards. More on stackoverflow.com
🌐 stackoverflow.com
Are `prisma.$transactions` wrapped inside `BEGIN` and `COMMIT` for postgres?
Are `prisma.$transactions` wrapped inside `BEGIN` and `COMMIT` for postgres? More on github.com
🌐 github.com
1
1
April 9, 2024
API for interactive transactions with dependencies between write-operations
There already is a GitHub issue asking for a way to submit multiple mutations within the same HTTP request where all mutations are executed as one transaction. However, this feature does not allow ... More on github.com
🌐 github.com
122
January 10, 2019
🌐
Medium
medium.com › @moiserushanika2006 › mastering-database-rollbacks-with-prismas-transactional-finesse-9156b8319bb1
Mastering Database Rollbacks with Prisma’s Transactional Finesse | by Moise rushanika | Medium
December 23, 2023 - // main.ts import { PrismaClient } from './generated/client'; const prisma = new PrismaClient(); async function run() { // Start a transaction const transaction = await prisma.$transaction([ prisma.user.create({ data: { name: 'Moise rushanika', email: 'moise@example.com', }, }), prisma.user.create({ data: { name: 'NGANULO RUSHANIKA', email: 'moise@example.com', // Intentional conflict to trigger a rollback }, }), ]); // Commit the transaction if successful await transaction.$commit(); console.log('Transaction completed successfully.'); } run() .catch((error) => { // Handle the error and rollback the transaction console.error('Transaction failed:', error.message); prisma.$rollback(); }) .finally(async () => { // Disconnect from the database await prisma.$disconnect(); });
🌐
GitHub
github.com › prisma › prisma › issues › 22309
Manual transaction commit, rollback · Issue #22309 · prisma/prisma
December 7, 2023 - type PrismaFlatTransactionClient = Prisma.TransactionClient & { $commit: () => Promise<void>; $rollback: () => Promise<void>; }; @Injectable() export class TransactionInterceptor implements NestInterceptor { readonly ROLLBACK = { [Symbol.for('prisma.client.extension.rollback')]: true, }; public readonly prisma = new PrismaClient({ log: ["query"] }).$extends({ client: { async $begin() { const prisma = Prisma.getExtensionContext(this); let setTxClient: (txClient: Prisma.TransactionClient) => void; let commit: () => void; let rollback: () => void; // a promise for getting the tx inner client cons
Author   prisma
🌐
Prisma Client Python
prisma-client-py.readthedocs.io › en › stable › reference › transactions
Transactions - Prisma Client Python
In the case that this example runs ... are committed when the context manager exits, meaning that queries running elsewhere in your application will then access the updated data. ... Transactions support alongside model based queries is not stable. Do not rely on Model.prisma() always using ...
🌐
DEV Community
dev.to › reyronald › dealing-with-open-database-transactions-in-prisma-3clk
Dealing with open database transactions in Prisma - DEV Community
February 23, 2025 - In my solution, calling runInDbTransaction represents that BEGIN statement, and closing the scope of its callback argument represents the COMMIT phase to end the transaction. Although I understand Prisma's decision for its current transaction API, I feel we would be better off with an API that more closely resembles how it works in SQL.
🌐
Prisma
prisma.io › dataguide › mysql › inserting-and-modifying-data › using-transactions
Using Transactions | Inserting and modifying data | MySQL | Data Guide
Within a transaction, the executed statements can only affect the environment within the transaction itself. From inside the transaction, statements can modify data and the results are immediately visible. From the outside, no changes are made until the transaction is committed, at which time all of the actions within the transaction become visible at once.
🌐
DEV Community
dev.to › this-is-learning › its-prisma-time-transactions-ji5
It's Prisma Time - Transactions - DEV Community
February 16, 2023 - The first method to do a transaction in Prisma is using the $transaction method. This method accepts a list of operations that are performed in a single transaction. If all of these operations are successful the transaction does the commit otherwise ...
Find elsewhere
🌐
Prisma
prisma.io › dataguide › mongodb › mongodb-transactions
MongoDB Transactions - How to Use and Manage Them
Within a transaction, the executed statements can only affect the environment within the transaction itself. From inside the transaction, statements can modify data and the results are immediately visible. From the outside, no changes are made until the transaction is committed, at which time all of the actions within the transaction become visible at once.
🌐
Prisma
prisma.io › home › transactions › transactions › transactions › transactions
Transactions in Prisma Next | Prisma Documentation
3 weeks ago - They commit immediately and won't roll back with the rest of the callback. Use the tx handle for every query inside the callback: tx.orm for models, tx.sql and tx.execute for SQL builder plans.
🌐
Stack Overflow
stackoverflow.com › questions › 73179585 › using-prisma-and-transactions
typescript - Using Prisma and transactions? - Stack Overflow
In my mind, that would make Prisma calling the rollback-function of the transaction. But no. Everything is saved in the database. I have also been trying to call raw SQL and when doing so, I can use: await globals.prisma.$executeRawUnsafe("begin"); await globals.prisma.$executeRawUnsafe("... just random update"); //await globals.prisma.$executeRawUnsafe("rollback"); await globals.prisma.$executeRawUnsafe("commit");
🌐
Prisma
prisma.io › blog › how-prisma-supports-transactions-x45s1d5l0ww1
Learn How Prisma Supports Database Transactions | Prisma
September 8, 2020 - In general, a transaction allows developers to group a set of read- and/or write-operations into a single operation which is guaranteed to succeed ("the transaction is committed") or fail ("the transaction is aborted and rolled back") as a whole.
🌐
Howtoprisma
howtoprisma.com › blog › how-to-use-transactions-in-prisma
Home | Holodeck
March 30, 2023 - Ryan has been teaching full stack web development through screencasts and courses since 2015. He's worked for auth0 and Prisma and is the founder of Elevate Digital, a full-service web application development agency.
🌐
GitHub
github.com › prisma › prisma › issues › 1844
API for interactive transactions with dependencies between write-operations · Issue #1844 · prisma/prisma
January 10, 2019 - prisma.transaction(async tx => { const user = await tx.createUser({ name, }) // compute some stuff await tx.updateOrder(user.id) await tx.commit() }) This is currently not possible with the Prisma API as it would require having a long-running connection where the results of the operations are sent back and forth between Prisma and the database.
Author   prisma
🌐
Stack Overflow
stackoverflow.com › questions › 66863807 › how-to-use-transaction-api-in-this-scenario
prisma - How to use $transaction API in this scenario? - Stack Overflow
That's not possible, Prisma's API is lazy by default so no insert will happen before the transaction. I can send you an example as well if possible. 2021-03-31T06:53:14.5Z+00:00 ... If i just use create() with no await and open the debug option of prisma, the console shows BEGIN; INSERT...; COMMIT;...
🌐
GitHub
github.com › prisma › prisma › issues › 9083
Middlewares to include transaction and for it to have an `afterCommit` hook · Issue #9083 · prisma/prisma
September 2, 2021 - That way I can run logic with and/or after the transaction is committed. ... // schema.prisma generator client { provider = "prisma-client-js" previewFeatures = ["interactiveTransactions"] } datasource db { provider = "postgresql" url = env("DATABASE_URL") } model Car { model String } // middleware.ts export const middleware = (prisma: PrismaClient) => { prisma.$use(async (params, next) => { console.log('params', params) // params.tPrisma = type PrismaTransactionClient params.tPrisma.afterCommit(fireCarCreatedEvent) }) } // prisma.ts import { middleware } from './middleware' const prisma = new PrismaClient() middleware(prisma) export { prisma } // main.js import { prisma } from './prisma.ts' const main = async () => { await prisma.$transaction(async (tPrisma) => { return tPrisma.car.create({ data: { model: 'abc' } }) }) } main() .then(() => process.exit(0))
Author   prisma
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.

🌐
GitHub
github.com › prisma › prisma › issues › 12458
Callback-free interactive transactions · Issue #12458 · prisma/prisma
March 21, 2022 - kind/featureA request for a new feature.A request for a new feature.tech/typescriptIssue for tech TypeScript.Issue for tech TypeScript.topic: $transactionRelated to .$transaction(...) Client APIRelated to .$transaction(...) Client APItopic: extend-clientExtending the Prisma ClientExtending the Prisma Clienttopic: interactiveTransactionstopic: rollbacktopic: transaction ... Some users are asking for a less restricted way for opening an interactive transaction. Instead of having a callback for the transaction, there would be manual calls to $begin, $commit, and $rollback.
Author   prisma
🌐
GitHub
github.com › prisma › prisma › issues › 11920
`onCommit`/`onRollback` callbacks for interactive transactions · Issue #11920 · prisma/prisma
February 19, 2022 - As an alternative we can use events like prisma.on('commit', async () => {....}) ... kind/featureA request for a new feature.A request for a new feature.topic: $transactionRelated to .$transaction(...) Client APIRelated to .$transaction(...) Client APItopic: extend-clientExtending the Prisma ClientExtending the Prisma Clienttopic: interactiveTransactionstopic: postgresqltopic: rollback
Author   prisma