Careeroza
Real World Example
Placing an Order in a Transaction
When thousands of people buy during a Flipkart Big Billion Days sale, stock must never go below zero and an order must never be half-saved. Use a database transaction with a conditional stock update:
// lib/dal/checkout.ts
import 'server-only';
import { prisma } from '@/lib/prisma';
import { verifySession } from './orders';
export async function placeOrder(items: { productId: number; qty: number }[]) {
const user = await verifySession();
return prisma.$transaction(async (tx) => {
let totalPaise = 0;
for (const item of items) {
// decrement only if enough stock: atomic in PostgreSQL
const updated = await tx.product.updateMany({
where: { id: item.productId, stock: { gte: item.qty } },
data: { stock: { decrement: item.qty } },
});
if (updated.count === 0) throw new Error('OUT_OF_STOCK:' + item.productId);
const p = await tx.product.findUniqueOrThrow({ where: { id: item.productId }, select: { price: true } });
totalPaise += Math.round(Number(p.price) * 100) * item.qty;
}
return tx.order.create({
data: { userId: user.id, status: 'PENDING_PAYMENT', totalPaise, items: { create: items } },
select: { id: true, totalPaise: true },
});
});
}Why the Conditional Update
Example
Two buyers race for the last unit. "Read, then write" oversells; a conditional update does not:
type Product = { id: number; stock: number };
async function readThenWrite(p: Product, buyer: string) {
const stock = p.stock; // both read 1
await Promise.resolve(); // the other request runs here
if (stock >= 1) { p.stock = stock - 1; return buyer + ' bought'; }
return buyer + ' sold out';
}
async function conditionalUpdate(p: Product, buyer: string) {
await Promise.resolve();
if (p.stock >= 1) { p.stock -= 1; return buyer + ' bought'; } // like UPDATE ... WHERE stock >= 1
return buyer + ' sold out';
}
async function main() {
const a = { id: 1, stock: 1 };
console.log(await Promise.all([readThenWrite(a, 'Ravi'), readThenWrite(a, 'Anita')]), 'stock =', a.stock, '(sold 2, had 1!)');
const b = { id: 1, stock: 1 };
console.log(await Promise.all([conditionalUpdate(b, 'Ravi'), conditionalUpdate(b, 'Anita')]), 'stock =', b.stock);
}
main();Output
[ 'Ravi bought', 'Anita bought' ] stock = 0 (sold 2, had 1!) [ 'Ravi bought', 'Anita sold out' ] stock = 0