Database Integration with PostgreSQL and PrismaLesson 5.3
Database transactions in Prisma — when and how to use them
ACID transactions, prisma.$transaction, sequential vs interactive transactions, rollback on error, use cases, avoiding partial updates
Database Transactions with Prisma
A transaction groups multiple database operations into one atomic unit — either all succeed or all roll back. Use transactions any time two or more writes must stay consistent.
Sequential Transactions
// Both operations execute atomically
const [debit, credit] = await prisma.$transaction([
prisma.account.update({ where: { id: 1 }, data: { balance: { decrement: 100 } } }),
prisma.account.update({ where: { id: 2 }, data: { balance: { increment: 100 } } })
]);Interactive Transactions (with rollback logic)
await prisma.$transaction(async (tx) => {
const sender = await tx.account.findUnique({ where: { id: 1 } });
if (sender.balance < 100) {
throw new Error('Insufficient funds'); // automatically rolls back
}
await tx.account.update({ where: { id: 1 }, data: { balance: { decrement: 100 } } });
await tx.account.update({ where: { id: 2 }, data: { balance: { increment: 100 } } });
});Use interactive transactions when you need to read data and make decisions inside the transaction. Throwing any error inside the callback automatically triggers a rollback. Sequential transactions are simpler but cannot branch based on read results. Avoid long transactions — they hold locks and degrade throughput.
