1 분 소요

Prisma $transaction vs Promise

1️⃣ Promise란 무엇인가요?

Promise는 자바스크립트에서 비동기 작업(Asynchronous)을 처리할 때 사용하는 도구입니다. 비동기 작업이란 “지금 요청하지만, 결과는 나중에 나오는 작업”(예: DB 조회, 파일 읽기)을 말합니다.

Promise는 세 가지 상태를 가집니다:

  1. Pending (대기): 아직 작업이 진행 중인 상태.
  2. Fulfilled (이행): 작업이 성공적으로 끝난 상태 (resolve).
  3. Rejected (거부): 작업이 에러로 끝난 상태 (reject).

예시

// 두 작업을 변수에 담으면 바로 실행이 시작됩니다. (직렬)
const countPromise = prisma.video.count(...);
const listPromise = prisma.video.findMany(...);

// Promise.all은 배열 안의 모든 작업이 끝날 때까지 동시에 기다립니다. (병렬)
const [totalCount, videos] = await Promise.all([countPromise, listPromise]);

2️⃣ Prisma vs Promise

Prisma의 모든 함수(예: count, findMany)는 호출 즉시 결과를 주는 게 아니라, DB에 다녀올 때까지 시간이 걸리는 Promise 객체를 반환합니다.

  • 동기 방식 (직렬): count가 끝날 때까지 기다렸다가, 그 다음 findMany를 실행합니다. 전체 시간이 더 오래 걸립니다.
  • Promise.all 방식 (병렬): countfindMany동시에 DB에 요청합니다. 두 작업 중 더 오래 걸리는 작업의 시간만큼만 기다리면 되므로 훨씬 빠릅니다

❗️ 주의할점

Prisma는 내부적으로 커넥션 풀(Connection Pool)을 사용합니다. Promise.all로 너무 많은 쿼리를 한 번에 날리면 DB 연결 한도를 초과할 수 있으니, 2~3개의 연관된 쿼리를 묶을 때 사용하는 것이 가장 이상적입니다.

⭐️ 결과/결론

  • Promise는 비동기 작업의 결과표입니다.
  • Promise.all은 여러 작업을 동시에 처리해서 API 응답 속도를 높이기 위해 사용합니다.
  • Prisma를 쓸 때 병렬 조회가 필요한 경우(예: 목록과 전체 개수 조회) 필수적인 기술입니다

3️⃣ $transaction vs Promise

구분 트랜잭션 ($transaction) 병렬 처리 (Promise.all)
핵심 목적 데이터의 무결성 (전부 성공하거나, 전부 취소되거나) 성능 최적화 (여러 작업을 동시에 실행해서 응답 속도 단축)
주요 작업 생성, 수정, 삭제 (Write) 단순 조회 (Read)
작동 방식 하나라도 실패하면 전체 롤백(Rollback) 각각 독립적으로 실행 (하나가 실패해도 나머지에 직접 영향 없음)

Promise를 사용하는 경우

  • 데이터 조회의 경우: 영상 개수(count)를 가져오는 것과 영상 목록(findMany)을 가져오는 것은 서로 독립적인 작업입니다. 굳이 하나가 실패했다고 해서 다른 하나를 취소(롤백)할 이유가 없습니다.
  • 성능이 최우선: 영상 리스트를 불러올 때 사용자가 기다리는 시간을 최소화하는 것이 가장 중요하므로, 두 쿼리를 동시에 날리는 Promise.all이 가장 적합한 선택입니다.

$transaction을 사용하는 경우

트랜잭션은 “이 작업들이 한 묶음으로 처리되지 않으면 데이터가 꼬인다”라고 판단될 때 씁니다.

  • 예시: 사용자 계정 삭제 시
    1. User 테이블에서 사용자 삭제
    2. 해당 사용자의 Project들 모두 삭제
      • 만약 1번은 성공했는데 2번에서 서버가 꺼지면, 주인 없는 프로젝트 데이터가 남게 됩니다. 이럴 때 트랜잭션을 써서 둘 다 성공하거나, 아니면 아예 없었던 일로 만들어야 합니다.

⭐️ 결과/결론

  • 조회(Read) 작업에서 속도를 높이고 싶을 때는 *Promise.all을 씁니다.
  • 수정/삭제(Write) 작업에서 데이터 안전을 보장하고 싶을 때는 *$transaction을 씁니다.

댓글남기기