[Node.js] 트랜젝션 vs Promise & 무한 스크롤
Prisma $transaction vs Promise
1️⃣ Promise란 무엇인가요?
Promise는 자바스크립트에서 비동기 작업(Asynchronous)을 처리할 때 사용하는 도구입니다. 비동기 작업이란 “지금 요청하지만, 결과는 나중에 나오는 작업”(예: DB 조회, 파일 읽기)을 말합니다.
Promise는 세 가지 상태를 가집니다:
- Pending (대기): 아직 작업이 진행 중인 상태.
- Fulfilled (이행): 작업이 성공적으로 끝난 상태 (
resolve). - 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 방식 (병렬):
count와findMany를 동시에 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을 사용하는 경우
트랜잭션은 “이 작업들이 한 묶음으로 처리되지 않으면 데이터가 꼬인다”라고 판단될 때 씁니다.
- 예시: 사용자 계정 삭제 시
User테이블에서 사용자 삭제- 해당 사용자의
Project들 모두 삭제- 만약 1번은 성공했는데 2번에서 서버가 꺼지면, 주인 없는 프로젝트 데이터가 남게 됩니다. 이럴 때 트랜잭션을 써서 둘 다 성공하거나, 아니면 아예 없었던 일로 만들어야 합니다.
⭐️ 결과/결론
- 조회(Read) 작업에서 속도를 높이고 싶을 때는 *
Promise.all을 씁니다. - 수정/삭제(Write) 작업에서 데이터 안전을 보장하고 싶을 때는 *
$transaction을 씁니다.
댓글남기기