<img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=1063935717132479&amp;ev=PageView&amp;noscript=1 https://www.facebook.com/tr?id=1063935717132479&amp;ev=PageView&amp;noscript=1 "> Transactions

Transactions

A transaction groups several writes so they all succeed or all fail together. If any step throws, the database undoes everything as if none of it happened. Think of a bank transfer: money leaves one account and arrives in another. You never want one half to happen without the other.

How to use it

import { PrismaClient } from "@prisma/client";

const prisma = new PrismaClient();

// $transaction hands you a scoped `tx` client; everything on it commits together
await prisma.$transaction(async (tx) => {
  await tx.account.update({
    where: { id: fromAccount },
    data: { balance: { decrement: 100 } },
  });

  await tx.account.update({
    where: { id: toAccount },
    data: { balance: { increment: 100 } },
  });
});
// If the second update throws, the first is rolled back automatically.
Both succeed → commit A −100 ✓ B +100 ✓ COMMIT both writes saved Second throws → rollback A −100 ✓ B +100 ✗ ROLLBACK A −100 is undone too
Inside $transaction the two writes share one fate. If the second throws, the first is rolled back, so a balance is never left half-moved.

Common reasons you may need one

  • Any operation that writes to more than one row or table and must agree
  • Moving a value from one place to another (transfers, inventory, balances)
  • Steps where a partial result would leave your data in a broken state

If you're only doing a single write, you don't need an explicit transaction. One statement is already all-or-nothing.

Exercise

Node challenge · runs in your browser