Transactions and batch queries {prisma}

aliases
No value
tags
prisma/client
description
No value
links
https://www.prisma.io/docs/orm/prisma-client/queries/transactions 0180 Prisma ๐ŸŒˆ
status
No value
project
true
area
false
resource
false
title
Transactions and batch queries {prisma}
created
2025-07-08T22:29:37
updated
2026-05-15T00:00:00

๋ฌธ์ œ์˜์‹

Transactions and batch queries๋ฅผ ์ฃผ์˜๊นŠ๊ฒŒ ์ฝ์€ ํ›„ ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ๊ฐ€ ์ง€์ผœ์•ผ ํ•˜๋Š” ํŠธ๋žœ์žญ์…˜ ๊ฒฝ๊ณ„๋ฅผ ํ”„๋ฆฌ์ฆˆ๋งˆ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์–ด๋–ป๊ฒŒ ๋‹ฌ์„ฑํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ์•„๋ด…์‹œ๋‹ค.

Prisma Client๋Š” ํŠธ๋žœ์žญ์…˜์„ ํ•˜๋‚˜์˜ API๋กœ๋งŒ ์ œ๊ณตํ•˜์ง€ ์•Š๋Š”๋‹ค. ๊ฐ™์€ "์—ฌ๋Ÿฌ ์ž‘์—…์„ ํ•œ ๋ฒˆ์— ์„ฑ๊ณตํ•˜๊ฑฐ๋‚˜ ์‹คํŒจํ•˜๊ฒŒ ๋งŒ๋“ ๋‹ค"๋Š” ๋ชฉ์ ์ด๋ผ๋„, ์ž‘์—…์˜ ์˜์กด์„ฑ์— ๋”ฐ๋ผ ์„ ํƒ์ง€๊ฐ€ ๋‹ฌ๋ผ์ง„๋‹ค.

์ƒํ™ฉ Prisma์˜ ์„ ํƒ์ง€ ํ•ต์‹ฌ ์งˆ๋ฌธ
๊ฐ™์€ ๋ชจ๋ธ์˜ ์—ฌ๋Ÿฌ ๋ ˆ์ฝ”๋“œ๋ฅผ ํ•œ ๋ฒˆ์— ๋ณ€๊ฒฝํ•œ๋‹ค Batch operations ๊ฐ ๋ ˆ์ฝ”๋“œ๊ฐ€ ์„œ๋กœ ๋…๋ฆฝ์ ์ธ๊ฐ€?
๋ถ€๋ชจ์™€ ์ž์‹ ๋ ˆ์ฝ”๋“œ๋ฅผ ํ•จ๊ป˜ ์ƒ์„ฑ/์ˆ˜์ •ํ•œ๋‹ค Nested writes ๋’ค ์ž‘์—…์ด ์•ž ์ž‘์—…์˜ ์ƒ์„ฑ ID์— ์˜์กดํ•˜๋Š”๊ฐ€?
์—ฌ๋Ÿฌ ์ฟผ๋ฆฌ ์‚ฌ์ด์— ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋กœ์ง์ด ํ•„์š”ํ•˜๋‹ค Interactive transactions ์ฝ๊ณ  ํŒ๋‹จํ•œ ๋’ค ๊ฐ™์€ ์›์ž์  ๊ฒฝ๊ณ„ ์•ˆ์—์„œ ๋‹ค์‹œ ์จ์•ผ ํ•˜๋Š”๊ฐ€?
์„œ๋กœ ๋‹ค๋ฅธ ๋ชจ๋ธ์˜ ๋…๋ฆฝ ์ž‘์—…์„ ํ•œ ๋ฒˆ์— ๋ฌถ๋Š”๋‹ค $transaction([]) ๊ฐ ์ฟผ๋ฆฌ๋ฅผ ๋ฏธ๋ฆฌ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š”๊ฐ€?

Batch operations

Batch operations๋Š” ๊ฐ™์€ ๋ชจ๋ธ์— ๋Œ€ํ•œ ๋‹ค๊ฑด ์ž‘์—…์„ ํ•˜๋‚˜์˜ ์ฟผ๋ฆฌ๋กœ ํ‘œํ˜„ํ•œ๋‹ค. Prisma ๋ฌธ์„œ์—์„œ ํŠธ๋žœ์žญ์…˜์œผ๋กœ ์‹คํ–‰๋œ๋‹ค๊ณ  ์„ค๋ช…ํ•˜๋Š” ๋Œ€ํ‘œ API๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ์—ฌ๋Ÿฌ ์ด๋ฉ”์ผ์„ ์ฝ์Œ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ธฐ๋Šฅ์€ ๊ฐ ์ด๋ฉ”์ผ์˜ ์—…๋ฐ์ดํŠธ๊ฐ€ ์„œ๋กœ ๋…๋ฆฝ์ ์ด๋‹ค. ์ด๋Ÿด ๋•Œ๋Š” ์ด๋ฉ”์ผ ํ•˜๋‚˜๋งˆ๋‹ค update๋ฅผ ๋ฐ˜๋ณตํ•˜๊ฑฐ๋‚˜ $transaction([])์— ์ˆ˜์‹ญ ๊ฐœ์˜ update๋ฅผ ๋„ฃ๊ธฐ๋ณด๋‹ค updateMany๊ฐ€ ๋” ๋‹จ์ˆœํ•˜๋‹ค.

await prisma.email.updateMany({
  where: {
    userId,
    unread: true,
  },
  data: {
    unread: false,
  },
})

Batch operations๋Š” "๊ฐ™์€ ๋ชจ๋ธ, ๊ฐ™์€ ๋ณ€๊ฒฝ ๊ทœ์น™, ๋…๋ฆฝ์ ์ธ ๋ ˆ์ฝ”๋“œ"๋ผ๋Š” ์กฐ๊ฑด์ด ๋งž์„ ๋•Œ ๊ฐ€์žฅ ๋จผ์ € ๊ณ ๋ คํ•  ์„ ํƒ์ง€๋‹ค. ๋‹ค๋งŒ ์—ฌ๋Ÿฌ ๋ชจ๋ธ์„ ํ•จ๊ป˜ ๋‹ค๋ฃจ๊ฑฐ๋‚˜, ๊ฐ ๋ ˆ์ฝ”๋“œ๋ณ„๋กœ ๋‹ค๋ฅธ ๊ด€๊ณ„ ์ž‘์—…์ด ํ•„์š”ํ•˜๋ฉด ์ ํ•ฉํ•˜์ง€ ์•Š๋‹ค.

Nested writes

Nested writes๋Š” ๊ด€๋ จ๋œ ๋ ˆ์ฝ”๋“œ๋“ค์„ ํ•˜๋‚˜์˜ Prisma ์ฟผ๋ฆฌ ์•ˆ์—์„œ ํ•จ๊ป˜ ์“ฐ๋Š” ๋ฐฉ์‹์ด๋‹ค. ์‚ฌ์šฉ์ž๋Š” ํ•œ ๋ฒˆ์˜ create ๋˜๋Š” update๋ฅผ ํ˜ธ์ถœํ•˜์ง€๋งŒ, Prisma๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ ๊ด€๋ จ ์“ฐ๊ธฐ ์ž‘์—…๋“ค์„ ํ•˜๋‚˜์˜ ํŠธ๋žœ์žญ์…˜์œผ๋กœ ๋ฌถ๋Š”๋‹ค.

const team = await prisma.team.create({
  data: {
    name: 'Aurora Adventures',
    members: {
      create: {
        email: 'alice@prisma.io',
      },
    },
  },
})

์ด ๋ฐฉ์‹์ด ์ค‘์š”ํ•œ ์ด์œ ๋Š” dependent writes ๋•Œ๋ฌธ์ด๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด Team์„ ๋งŒ๋“  ๋’ค ๊ทธ Team.id๋ฅผ ์‚ฌ์šฉํ•ด User๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค๋ฉด, ๋’ค ์ž‘์—…์€ ์•ž ์ž‘์—…์˜ ๊ฒฐ๊ณผ์— ์˜์กดํ•œ๋‹ค. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ ID๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ตฌ์กฐ๋ผ๋ฉด $transaction([]) ๋ฐฐ์—ด ์•ˆ์˜ ๋‹ค์Œ ์ฟผ๋ฆฌ๋กœ ๊ทธ ID๋ฅผ ๋„˜๊ธธ ์ˆ˜ ์—†๋‹ค. ์ด๋Ÿฐ ๊ฒฝ์šฐ์—๋Š” Nested writes๊ฐ€ ๋” ์ž์—ฐ์Šค๋Ÿฝ๊ณ  ์•ˆ์ „ํ•˜๋‹ค.

Can I use nested writes with bulk operations?

No - neither updateMany nor deleteMany currently supports nested writes. For example, you cannot delete multiple teams and all of their members (a cascading delete):

await prisma.team.deleteMany({
  where: {
    id: {
      in: [2, 99, 2, 11],
    },
  },
  data: {
    members: {}, // Cannot access members here
  },
})

Nested writes๋Š” ๊ด€๊ณ„ ๊ทธ๋ž˜ํ”„๋ฅผ ํ•œ ๋ฒˆ์— ์“ฐ๊ธฐ ์ข‹์ง€๋งŒ, bulk operation๊ณผ ๊ฒฐํ•ฉ๋˜์ง€๋Š” ์•Š๋Š”๋‹ค. updateMany, deleteMany ์•ˆ์—์„œ ๊ด€๊ณ„ ํ•„๋“œ๋ฅผ ํƒ€๊ณ  ๋“ค์–ด๊ฐ€ ์ž์‹ ๋ ˆ์ฝ”๋“œ๋ฅผ ํ•จ๊ป˜ ์ˆ˜์ •ํ•˜๊ฑฐ๋‚˜ ์‚ญ์ œํ•  ์ˆ˜๋Š” ์—†๋‹ค.

$transaction([]) API

$transaction([]) API๋Š” ์—ฌ๋Ÿฌ Prisma Client ์ฟผ๋ฆฌ๋ฅผ ๋ฐฐ์—ด๋กœ ๋„˜๊ฒจ ์ˆœ์„œ๋Œ€๋กœ ์‹คํ–‰ํ•˜๊ณ , ํ•˜๋‚˜๋ผ๋„ ์‹คํŒจํ•˜๋ฉด ์ „์ฒด๋ฅผ ๋กค๋ฐฑํ•œ๋‹ค. ์ฃผ๋กœ ์„œ๋กœ ๋‹ค๋ฅธ ๋ชจ๋ธ์˜ ๋…๋ฆฝ์ ์ธ ์ž‘์—…๋“ค์„ ํ•˜๋‚˜์˜ ์›์ž์  ๊ฒฝ๊ณ„๋กœ ๋ฌถ์„ ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

UseCase: ์—ฌ๋Ÿฌ ํ…Œ์ด๋ธ”์— ๊ฑธ์นœ Delete Operation

const id = 9 // User to be deleted

const deletePosts = prisma.post.deleteMany({
  where: {
    userId: id,
  },
})

const deleteMessages = prisma.privateMessage.deleteMany({
  where: {
    userId: id,
  },
})

const deleteUser = prisma.user.delete({
  where: {
    id: id,
  },
})

await prisma.$transaction([deletePosts, deleteMessages, deleteUser]) // Operations succeed or fail together

์—ฌ๊ธฐ์„œ๋Š” Post, PrivateMessage, User๋ผ๋Š” ์„œ๋กœ ๋‹ค๋ฅธ ๋ชจ๋ธ์„ ํ•จ๊ป˜ ์‚ญ์ œํ•ด์•ผ ํ•œ๋‹ค. ๋‹จ์ผ deleteMany๋กœ ํ‘œํ˜„ํ•  ์ˆ˜ ์—†๊ณ , ๊ฐ ์ฟผ๋ฆฌ๋Š” ์‚ญ์ œ ๋Œ€์ƒ ์‚ฌ์šฉ์ž ID๋งŒ ์•Œ๋ฉด ๋ฏธ๋ฆฌ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿฐ ๊ฒฝ์šฐ $transaction([])๊ฐ€ ์ ํ•ฉํ•˜๋‹ค.

UseCase: pre-computed ID๋ฅผ ์‚ฌ์šฉํ•˜๊ณ ์ž ํ•˜๋Š” ๊ฒฝ์šฐ

๋ฌธ์„œ์—์„œ๋Š” UUID๋ฅผ ์‚ฌ์šฉํ•˜์˜€์œผ๋‚˜, ๋‚ด๊ฐ€ ์•Œ๊ธฐ๋ก  ObjectId๋„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋‹จ์—์„œ ์ƒ์„ฑ์ด ๊ฐ€๋Šฅํ•˜๋‹ค๊ณ  ๋“ค์—ˆ๋Š”๋ฐ, ๊ตณ์ด Nested Write๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ ๋„ ๋…๋ฆฝ์ ์ธ ์˜คํผ๋ ˆ์ด์…˜๋“ค๋กœ ๋ถ„๋ฆฌํ•œ ๋‹ค์Œ ํ•˜๋‚˜์˜ ํŠธ๋žœ์žญ์…˜์œผ๋กœ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ๋„ ์ ๊ทน์ ์œผ๋กœ ๋„์ž…ํ•ด๋ณผ ์ˆ˜ ์žˆ๊ฒ ๋‹ค.

import { v4 } from 'uuid'

const teamID = v4()
const userID = v4()

await prisma.$transaction([
  prisma.user.create({
    data: {
      id: userID,
      email: 'alice@prisma.io',
      team: {
        id: teamID,
      },
    },
  }),
  prisma.team.create({
    data: {
      id: teamID,
      name: 'Aurora Adventures',
    },
  }),
])

ํ•ต์‹ฌ์€ ID๋ฅผ ๋ฏธ๋ฆฌ ์•Œ๊ณ  ์žˆ๋А๋ƒ์ด๋‹ค. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ ID๋ฅผ ์ƒ์„ฑํ•˜๋ฉด ๋’ค ์ฟผ๋ฆฌ๊ฐ€ ์•ž ์ฟผ๋ฆฌ์˜ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋‹ค๋ ค์•ผ ํ•˜๋ฏ€๋กœ Nested writes๊ฐ€ ๋งž๋‹ค. ๋ฐ˜๋Œ€๋กœ UUID๋‚˜ ObjectId์ฒ˜๋Ÿผ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ID๋ฅผ ๋จผ์ € ๊ณ„์‚ฐํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด, ๊ฐ ์ฟผ๋ฆฌ๋Š” ์„œ๋กœ์˜ ์‹คํ–‰ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š์•„๋„ ๋˜๋ฏ€๋กœ $transaction([])๋กœ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

๋‹ค๋งŒ Prisma ๋ฌธ์„œ๋„ ์ด๋ฏธ ์ž๋™ ์ƒ์„ฑ ID์™€ Nested writes๋ฅผ ์ž˜ ์“ฐ๊ณ  ์žˆ๋‹ค๋ฉด, ์ˆ˜๋™ ID ์ƒ์„ฑ๊ณผ $transaction([])๋กœ ๊ตณ์ด ๋ฐ”๊ฟ€ ๊ฐ•ํ•œ ์ด์œ ๋Š” ์—†๋‹ค๊ณ  ์„ค๋ช…ํ•œ๋‹ค. $transaction([])๋Š” "๋” ๊ฐ•๋ ฅํ•œ API"๋ผ๊ธฐ๋ณด๋‹ค "์ž‘์—…๋“ค์„ ๋…๋ฆฝ์ ์ธ PrismaPromise๋กœ ๋ฏธ๋ฆฌ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์„ ๋•Œ ์“ฐ๋Š” API"์— ๊ฐ€๊น๋‹ค.

Interactive transactions

Interactive transactions๋Š” ์ฝœ๋ฐฑ ํ˜•ํƒœ์˜ $transaction(async (tx) => { ... })์ด๋‹ค. ๋ฐฐ์—ดํ˜• $transaction([])์™€ ๋‹ฌ๋ฆฌ, ํŠธ๋žœ์žญ์…˜ ๋‚ด๋ถ€์—์„œ ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ์ฝ๊ณ  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋กœ์ง์œผ๋กœ ํŒ๋‹จํ•œ ๋‹ค์Œ ๋‹ค์Œ ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

const result = await prisma.$transaction(async (tx) => {
  const sender = await tx.account.update({
    where: { email: 'alice@prisma.io' },
    data: { balance: { decrement: 100 } },
  })

  if (sender.balance < 0) {
    throw new Error('Insufficient funds')
  }

  return tx.account.update({
    where: { email: 'bob@prisma.io' },
    data: { balance: { increment: 100 } },
  })
})

์ด ์˜ˆ์ œ๋Š” ์ „ํ˜•์ ์ธ read-modify-write ํ๋ฆ„์ด๋‹ค. ์ฒซ ๋ฒˆ์งธ ์“ฐ๊ธฐ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๊ณ  ์ž”์•ก์ด ์Œ์ˆ˜์ธ์ง€ ๊ฒ€์‚ฌํ•œ ๋’ค, ์กฐ๊ฑด์„ ๋งŒ์กฑํ•  ๋•Œ๋งŒ ๋‘ ๋ฒˆ์งธ ์“ฐ๊ธฐ๋ฅผ ์ˆ˜ํ–‰ํ•œ๋‹ค. ์ค‘๊ฐ„์— ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ํŠธ๋žœ์žญ์…˜์€ ๋กค๋ฐฑ๋œ๋‹ค.

Interactive transactions๋Š” ๊ฐ•๋ ฅํ•˜์ง€๋งŒ ๋น„์šฉ์ด ์žˆ๋‹ค. ํŠธ๋žœ์žญ์…˜์ด ์—ด๋ฆฐ ๋™์•ˆ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ปค๋„ฅ์…˜์„ ๋ถ™์žก๊ณ  ์žˆ์œผ๋ฏ€๋กœ, ์˜ค๋ž˜ ์‹คํ–‰๋˜๋Š” ๋กœ์ง์„ ๋„ฃ์œผ๋ฉด ์„ฑ๋Šฅ ์ €ํ•˜๋‚˜ deadlock ์œ„ํ—˜์ด ์ปค์ง„๋‹ค. Prisma ๋ฌธ์„œ๋„ ํŠธ๋žœ์žญ์…˜์„ ์งง๊ฒŒ ์œ ์ง€ํ•˜๋ผ๊ณ  ๊ถŒํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ํŠธ๋žœ์žญ์…˜ ๋‚ด๋ถ€์—๋Š” ๊ผญ ํ•„์š”ํ•œ DB ์ฝ๊ธฐ/์“ฐ๊ธฐ์™€ ์งง์€ ํŒ๋‹จ ๋กœ์ง๋งŒ ๋‘๋Š” ํŽธ์ด ์ข‹๋‹ค.

await prisma.$transaction(
  async (tx) => {
    // read -> decide -> write
  },
  {
    maxWait: 5000,
    timeout: 10000,
  },
)

์–ธ์ œ Batch, Nested, Interactive๋ฅผ ์จ์•ผ ํ• ๊นŒ?

1. ๋จผ์ € Batch operations๋ฅผ ์˜์‹ฌํ•œ๋‹ค

๊ฐ™์€ ๋ชจ๋ธ์˜ ์—ฌ๋Ÿฌ ๋ ˆ์ฝ”๋“œ๋ฅผ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ๋ฐ”๊พธ๋Š”๊ฐ€? ๊ทธ๋ ‡๋‹ค๋ฉด createMany, updateMany, deleteMany๋ฅผ ๋จผ์ € ๋ณธ๋‹ค.

์ด ๊ฒฝ์šฐ์—๋Š” ๊ฐœ๋ณ„ ๋ ˆ์ฝ”๋“œ๊ฐ€ ์„œ๋กœ ๋…๋ฆฝ์ ์ด๋‹ค. ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ ๊ด€์ ์—์„œ๋„ "๊ฐ ๋ ˆ์ฝ”๋“œ๋ณ„ ๋„๋ฉ”์ธ ๊ทœ์น™"์ด ์•„๋‹ˆ๋ผ "์ง‘ํ•ฉ์— ๋Œ€ํ•œ ๋™์ผํ•œ ์ƒํƒœ ์ „์ด"๋ผ๋ฉด batch operation์ด ๊ฐ€์žฅ ๋‹จ์ˆœํ•˜๋‹ค.

2. ์ƒ์„ฑ๋œ ID๋‚˜ ๊ด€๊ณ„ ๊ทธ๋ž˜ํ”„์— ์˜์กดํ•˜๋ฉด Nested writes๋ฅผ ์“ด๋‹ค

๋ถ€๋ชจ๋ฅผ ๋งŒ๋“ค๊ณ , ๊ทธ ๋ถ€๋ชจ์˜ ID๋กœ ์ž์‹์„ ๋งŒ๋“ค์–ด์•ผ ํ•˜๋Š”๊ฐ€? ํ•˜๋‚˜์˜ ์• ๊ทธ๋ฆฌ๊ฑฐํŠธ ์ƒ์„ฑ ๊ณผ์ •์—์„œ ๊ด€๊ณ„๋œ ๋ ˆ์ฝ”๋“œ๋“ค์ด ํ•จ๊ป˜ ์ƒ๊ฒจ์•ผ ํ•˜๋Š”๊ฐ€? ๊ทธ๋ ‡๋‹ค๋ฉด Nested writes๊ฐ€ ๋งž๋‹ค.

Nested writes๋Š” "๊ด€๊ณ„๋œ ์“ฐ๊ธฐ"๋ฅผ Prisma ์Šคํ‚ค๋งˆ์˜ ๊ด€๊ณ„ ๋ชจ๋ธ ๊ทธ๋Œ€๋กœ ํ‘œํ˜„ํ•œ๋‹ค. ํŠนํžˆ DB-generated ID๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ๋ฐฐ์—ดํ˜• $transaction([])๋ณด๋‹ค Nested writes๊ฐ€ ๋” ์ ํ•ฉํ•˜๋‹ค.

3. ๋…๋ฆฝ ์ฟผ๋ฆฌ ์—ฌ๋Ÿฌ ๊ฐœ๋ฅผ ์›์ž์ ์œผ๋กœ ๋ฌถ์œผ๋ฉด $transaction([])๋ฅผ ์“ด๋‹ค

์—ฌ๋Ÿฌ ๋ชจ๋ธ์„ ๊ฑด๋“œ๋ฆฌ์ง€๋งŒ ๊ฐ ์ฟผ๋ฆฌ๊ฐ€ ์„œ๋กœ์˜ ์‹คํ–‰ ๊ฒฐ๊ณผ์— ์˜์กดํ•˜์ง€ ์•Š๋Š”๊ฐ€? ๊ฐ Prisma ์ฟผ๋ฆฌ๋ฅผ ํŠธ๋žœ์žญ์…˜ ์‹œ์ž‘ ์ „์— ๋ฏธ๋ฆฌ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š”๊ฐ€? ๊ทธ๋ ‡๋‹ค๋ฉด $transaction([])๊ฐ€ ๋งž๋‹ค.

๋ฐฐ์—ดํ˜• $transaction([])๋Š” ์ˆœ์„œ๋Œ€๋กœ ์‹คํ–‰๋˜์ง€๋งŒ, ๋ฐฐ์—ด ์•ˆ์˜ ์ฟผ๋ฆฌ ์‚ฌ์ด์— ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋กœ์ง์„ ๋ผ์›Œ ๋„ฃ์ง€๋Š” ๋ชปํ•œ๋‹ค. ์•ž ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๊ณ  ๋‹ค์Œ ์ฟผ๋ฆฌ๋ฅผ ๊ตฌ์„ฑํ•ด์•ผ ํ•œ๋‹ค๋ฉด Interactive transactions๋กœ ๋„˜์–ด๊ฐ€์•ผ ํ•œ๋‹ค.

4. ์ฝ๊ณ  ํŒ๋‹จํ•œ ๋’ค ์จ์•ผ ํ•˜๋ฉด Interactive transactions๋ฅผ ์“ด๋‹ค

ํŠธ๋žœ์žญ์…˜ ๋‚ด๋ถ€์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ๋ฆ„์ด ํ•„์š”ํ•˜๋ฉด Interactive transactions๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

  1. ํ˜„์žฌ ์ƒํƒœ๋ฅผ ์ฝ๋Š”๋‹ค.
  2. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ฝ”๋“œ๋กœ ๋„๋ฉ”์ธ ์กฐ๊ฑด์„ ๊ฒ€์‚ฌํ•œ๋‹ค.
  3. ์กฐ๊ฑด์— ๋”ฐ๋ผ ๋‹ค์Œ ์“ฐ๊ธฐ๋ฅผ ์‹คํ–‰ํ•˜๊ฑฐ๋‚˜ ์˜ˆ์™ธ๋ฅผ ๋˜์ง„๋‹ค.
  4. ์ „์ฒด ์ž‘์—…์„ ํ•˜๋‚˜์˜ ์›์ž์  ๊ฒฝ๊ณ„๋กœ ์„ฑ๊ณต/์‹คํŒจ์‹œํ‚จ๋‹ค.

์˜ˆ์‹œ๋Š” ๊ณ„์ขŒ ์ด์ฒด, ์žฌ๊ณ  ์ฐจ๊ฐ, ์„ ์ฐฉ์ˆœ ์ฐธ์—ฌ, ๋‚™๊ด€์  ๋™์‹œ์„ฑ ์ œ์–ด๊ฐ€ ํ•„์š”ํ•œ ์ƒํƒœ ์ „์ด ๋“ฑ์ด๋‹ค. ๋‹ค๋งŒ ํŠธ๋žœ์žญ์…˜ ๋‚ด๋ถ€์— ๋„คํŠธ์›Œํฌ ํ˜ธ์ถœ, ์‚ฌ์šฉ์ž ์ž…๋ ฅ ๋Œ€๊ธฐ, ๊ธด ๊ณ„์‚ฐ์„ ๋„ฃ์œผ๋ฉด ํŠธ๋žœ์žญ์…˜ ์‹œ๊ฐ„์ด ๊ธธ์–ด์ง„๋‹ค. Interactive transactions๋Š” "๋ณต์žกํ•œ ๋กœ์ง์„ ๋„ฃ์–ด๋„ ๋˜๋Š” ๊ณณ"์ด ์•„๋‹ˆ๋ผ "DB ์ƒํƒœ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์งง๊ฒŒ ํŒ๋‹จํ•ด์•ผ ํ•˜๋Š” ๊ณณ"์œผ๋กœ ๋ณด๋Š” ํŽธ์ด ์•ˆ์ „ํ•˜๋‹ค.

ํŒ๋‹จ ๊ทœ์น™ ์š”์•ฝ

flowchart TD
  A["์—ฌ๋Ÿฌ DB ์ž‘์—…์ด ํ•„์š”ํ•œ๊ฐ€?"] -->|์•„๋‹ˆ์˜ค| B["์ผ๋ฐ˜ Prisma query"]
  A -->|์˜ˆ| C["๊ฐ™์€ ๋ชจ๋ธ์˜ ์—ฌ๋Ÿฌ ๋ ˆ์ฝ”๋“œ์— ๊ฐ™์€ ๋ณ€๊ฒฝ์ธ๊ฐ€?"]
  C -->|์˜ˆ| D["Batch operations"]
  C -->|์•„๋‹ˆ์˜ค| E["๊ด€๊ณ„๋œ ์“ฐ๊ธฐ์ด๋ฉฐ ์ƒ์„ฑ ID์— ์˜์กดํ•˜๋Š”๊ฐ€?"]
  E -->|์˜ˆ| F["Nested writes"]
  E -->|์•„๋‹ˆ์˜ค| G["๊ฐ ์ฟผ๋ฆฌ๋ฅผ ๋ฏธ๋ฆฌ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š”๊ฐ€?"]
  G -->|์˜ˆ| H["$transaction([])"]
  G -->|์•„๋‹ˆ์˜ค| I["Interactive transactions"]
์„ ํƒ์ง€ ์ž˜ ๋งž๋Š” ๊ฒฝ์šฐ ํ”ผํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ
Batch operations ๊ฐ™์€ ๋ชจ๋ธ์˜ ๋…๋ฆฝ ๋ ˆ์ฝ”๋“œ๋“ค์„ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ๋ณ€๊ฒฝ ๊ด€๊ณ„ ํ•„๋“œ๋ฅผ ํ•จ๊ป˜ ์“ฐ๊ฑฐ๋‚˜ ๋ ˆ์ฝ”๋“œ๋ณ„ ๋‹ค๋ฅธ ๋„๋ฉ”์ธ ํŒ๋‹จ์ด ํ•„์š”ํ•จ
Nested writes ๊ด€๊ณ„๋œ ๋ ˆ์ฝ”๋“œ๋ฅผ ํ•œ ๋ฒˆ์— ์“ฐ๊ณ , ์ƒ์„ฑ ID ์˜์กด์„ฑ์ด ์žˆ์Œ ๊ฐ™์€ ๋ชจ๋ธ์˜ ๋Œ€๋Ÿ‰ ์—…๋ฐ์ดํŠธ/์‚ญ์ œ๋ฅผ ๊ด€๊ณ„ ์ž‘์—…๊ณผ ํ•จ๊ป˜ ์ฒ˜๋ฆฌํ•˜๋ ค ํ•จ
$transaction([]) ์„œ๋กœ ๋‹ค๋ฅธ ๋ชจ๋ธ์˜ ๋…๋ฆฝ ์ฟผ๋ฆฌ๋ฅผ ์›์ž์ ์œผ๋กœ ๋ฌถ์Œ ์•ž ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๋กœ ๋’ค ์ฟผ๋ฆฌ๋ฅผ ๊ตฌ์„ฑํ•ด์•ผ ํ•จ
Interactive transactions read-modify-write, ๋„๋ฉ”์ธ ์กฐ๊ฑด ๊ฒ€์‚ฌ, ์งง์€ ์ƒํƒœ ์ „์ด ๊ธด ์ž‘์—…, ์™ธ๋ถ€ API ํ˜ธ์ถœ, ์‚ฌ์šฉ์ž ์ž…๋ ฅ ๋Œ€๊ธฐ, ๋‹จ์ˆœ batch ์ฒ˜๋ฆฌ

๊ฒฐ๋ก ์ ์œผ๋กœ Prisma์—์„œ ํŠธ๋žœ์žญ์…˜์„ ๊ณ ๋ฅด๋Š” ๊ธฐ์ค€์€ "์–ผ๋งˆ๋‚˜ ๋ณต์žกํ•œ๊ฐ€"๊ฐ€ ์•„๋‹ˆ๋ผ ์ฟผ๋ฆฌ ์‚ฌ์ด์˜ ์˜์กด์„ฑ์ด๋‹ค. ๋…๋ฆฝ์ ์ด๋ฉด Batch ๋˜๋Š” $transaction([]), ๊ด€๊ณ„ ์ƒ์„ฑ์— ์˜์กดํ•˜๋ฉด Nested writes, ์ค‘๊ฐ„ ํŒ๋‹จ์ด ํ•„์š”ํ•˜๋ฉด Interactive transactions๋ฅผ ์„ ํƒํ•œ๋‹ค.