11. Транзакции
Транзакции гарантируют атомарность операций: либо все изменения применяются успешно, либо ни одно из них не применяется. Это критически важно для сохранения согласованности данных.
Sequential transactions (пакетные транзакции)
Заголовок раздела «Sequential transactions (пакетные транзакции)»Самый простой способ: передать массив Prisma-операций в $transaction. Они выполнятся в одной транзакции:
const [user, post] = await prisma.$transaction([ prisma.post.create({ data: { title: 'Первый пост', authorId: 1 } }),])Interactive transactions (интерактивные транзакции)
Заголовок раздела «Interactive transactions (интерактивные транзакции)»Более гибкий подход с коллбэком. Позволяет принимать решения на основе промежуточных результатов:
const result = await prisma.$transaction(async (tx) => { // Проверить баланс const account = await tx.account.findUnique({ where: { id: fromAccountId }, })
if (account.balance < amount) { throw new Error('Недостаточно средств') }
// Снять средства await tx.account.update({ where: { id: fromAccountId }, data: { balance: { decrement: amount } }, })
// Зачислить средства await tx.account.update({ where: { id: toAccountId }, data: { balance: { increment: amount } }, })
return { success: true }})Timeout и настройки транзакции
Заголовок раздела «Timeout и настройки транзакции»await prisma.$transaction(async (tx) => { // ...операции...}, { maxWait: 5000, // максимальное ожидание начала транзакции (мс) timeout: 10000, // максимальное время выполнения (мс)})Вложенные операции
Заголовок раздела «Вложенные операции»Prisma также поддерживает вложенные записи без явных транзакций — они автоматически оборачиваются в транзакцию:
await prisma.user.create({ data: { posts: { create: [{ title: 'Пост 1' }, { title: 'Пост 2' }] }, profile: { create: { bio: 'Разработчик' } }, },})