Sikau

Prisma · Day 12 · about 35 min

Transactions

Batch and interactive $transaction for all-or-nothing work.

Never half a transfer

Moving money is two writes: take from one account, add to another. If the second fails, the first must be undone. A transaction groups writes so they all succeed or all roll back.

Two styles of $transaction

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

const prisma = new PrismaClient();

const [accounts, total] = await prisma.$transaction([
  prisma.account.findMany({ orderBy: { id: "asc" } }),
  prisma.account.aggregate({ _sum: { balance: true } }),
]);
console.log(accounts.length, total._sum.balance);

try {
  await prisma.$transaction(async (tx) => {
    await tx.account.update({ where: { owner: "Bikash" }, data: { balance: { decrement: 800 } } });
    const b = await tx.account.findUnique({ where: { owner: "Bikash" } });
    if (b.balance < 0) throw new Error("Insufficient funds");
    await tx.account.update({ where: { owner: "Asha" }, data: { balance: { increment: 800 } } });
  });
} catch (e) {
  console.log("rolled back:", e.message);
}
console.log(await prisma.account.findMany({ select: { owner: true, balance: true }, orderBy: { id: "asc" } }));

Keep interactive transactions short — they hold locks. Real Prisma also accepts { isolationLevel, timeout } options.

The rest of this lesson

  • Interactive transactionsexplain
  • Keeping transactions healthyexplain
  • Error inside?predict
  • Batch or interactive?match
  • Your turnwrite code
  • Badge quizquiz
  • What you learnedrecap

Continue this lesson free — run real code in your browser

Continue with Google

See all 15 lessons of Prisma