[DB][Prisma] transaction 설정하기

2024. 8. 28. 14:58·Backend/DB

DB API를 구현할 때는 한 번의 요청에 대해 여러 개의 함수를 실행하는 경우가 있습니다.

이 때 중요한 것은 모든 함수가 한 번에 수행되어야 하는 것인데,

중간에 오류가 발생해 처리가 중단되면, 처리가 완결되지 않은 불완전한 상태로 남기 때문입니다.

 

예를 들어 상품 재고를 관리하는 서버를 생각해봅시다.

아래 코드는 주문(order) 요청을 처리하는 엔드포인트로, 크게 두 가지 절차를 진행합니다.

    1. order 테이블에 새로운 주문정보에 해당하는 record를 추가

    2. 해당 주문에서 요청한 상품들의 수량만큼 product 테이블에서 각 record들의 quantity를 감소

(자세한 구현사항은 생략했습니다)

const prisma = new PrismaClient();

app.post('/orders', async (req, res) => {

  // ...

  // 1. order 테이블에 새로운 record를 추가합니다.
  const order = await prisma.order.create({
    // ...
  });
  
  // 2. 주문한 수량만큼 product 테이블에서 해당 record들의 quantity를 감소합니다.
  const queries = productIds.map((productId) =>
    prisma.product.update({
      // ...
    })
  );
  await Promise.all(queries);

  // ...
  
  res.status(201).send(order);
});

위 코드는 문법상으로는 문제가 되지 않습니다.

하지만, 만약 1. order record 추가가 된 후 2. product record quantity 감소 단계에서 에러가 발생하면 문제가 됩니다.

이 경우 엔드포인트는 오류와 함께 종료될 것이고, 주문은 처리되었지만 재고는 감소되지 않은 채로 끝나기 때문입니다.

 

따라서 엔드포인트 함수들을 안전하게 실행시키려면 1, 2 두 단계가 한 번에 실행되도록 해서

1, 2 모두 실행되지 않거나 모두 실행되는 경우만 존재하도록 해야 합니다.

 

Prisma에서는 $transaction 함수를 이용해서 이를 구현할 수 있습니다.

$transaction이 받는 인자는 transaction으로 묶을 함수들의 리스트입니다.

await PrismaClient.$transaction([func1, func2, ...]);

$transaction을 이용하면 위 예시를 아래와 같이 구현할 수 있습니다.

2번 단계는 transaction에서 반환할 필요가 없으므로 destructuring(...)처리를 하고, order만 반환하도록 했습니다.

const prisma = new PrismaClient();

app.post('/orders', async (req, res) => {

  // ...
  
  const [ order ] = await prisma.$transaction([
    // 1. order 테이블에 새로운 record를 추가합니다.
    const order = await prisma.order.create({
      // ...
    }),
    
    // 2. 주문한 수량만큼 product 테이블에서 해당 record들의 quantity를 감소합니다.
    ...productIds.map((productId) =>
      prisma.product.update({
        // ...
      })
    ),
  ]);

  // ...
  
  res.status(201).send(order);
});
728x90

'Backend > DB' 카테고리의 다른 글

[DB][Mongo] MongoDB에 대해서  (0) 2025.02.15
[PostgreSQL][Deploy] Render로 PostgreSQL DB 배포하기  (0) 2024.08.28
[DB][Prisma] foreign key를 이용해 일대다/일대일/다대다 관계 정의하기  (0) 2024.08.26
[DB][Prisma] PrismaClient 함수 정리  (0) 2024.08.25
[DB][Prisma] Prisma에서 데이터 시딩하기  (0) 2024.08.24
'Backend/DB' 카테고리의 다른 글
  • [DB][Mongo] MongoDB에 대해서
  • [PostgreSQL][Deploy] Render로 PostgreSQL DB 배포하기
  • [DB][Prisma] foreign key를 이용해 일대다/일대일/다대다 관계 정의하기
  • [DB][Prisma] PrismaClient 함수 정리
Rayi
Rayi
  • Rayi
    아카이브
    Rayi
  • 전체
    오늘
    어제
    • 분류 전체보기 (262)
      • CS (40)
        • ML (3)
        • CV (2)
        • PS (34)
      • Reveiw (17)
        • Paper (17)
        • Github (0)
      • Pytorch (5)
      • Language (58)
        • Python (7)
        • JavaScript (32)
        • TypeScript (16)
        • C++ (3)
      • IDE (12)
      • Git (13)
      • Frontend (71)
        • React (8)
        • SolidJS (20)
        • CSS (12)
      • UI (3)
      • Backend (15)
        • DB (17)
        • Node.js (11)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Express
    react
    CV
    ML
    postgresql
    CSS
    GAN
    figma
    ps
    deploy
    backend
    html
    js
    API
    UI
    PyTorch
    DB
    ts
    nodejs
    PRISMA
    Git
    vscode
    review
    frontend
    Three
    CS
    SOLID
    python
    mongo
    C++
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
Rayi
[DB][Prisma] transaction 설정하기
상단으로

티스토리툴바