Database/MongoDB

[몽고DB 완벽 가이드] 8. 트랜잭션

noahkim_ 2025. 4. 30. 09:58

크리스티나 초도로 , 섀넌 브래드쇼 , 오언 브라질 님의 "몽고DB 완벽 가이드" 책을 정리한 포스팅 입니다.

 

1. 트랜잭션 소개

  • 데이터베이스의 논리적 처리 단위
  • MongoDB는 복제 셋 및 샤드 클러스터 환경에서도 트랜잭션을 지원함

 

2. 트랜잭션 사용법

세션 기반 구조

  • MongoDB는 클라이언트-서버 간의 세션 관리를 기반으로 트랜잭션을 구현함
  • 분산 환경에서 클라이언트의 연속적인 작업을 추적하도록 하기 위함
구분 논리 세션 (Logical Session)
서버 세션 (Server Session)
정의 클라이언트의 트랜잭션 흐름 추적 객체
실제 트랜잭션 실행 담당
역할 트랜잭션 시퀀스, 시간, 인과관계 추적
요청 추적 및 세션 상태 관리
위치 클라이언트 애플리케이션 내부
MongoDB 서버 내부
관계 서버 세션과 연결되어 동작
논리 세션이 생성 시, 서버 세션을 통해 작업 실행
필요성 트랜잭션, 인과적 일관성, 재시도 가능한 쓰기 논리 세션을 실제 처리 단위로 연결하기 위함

 

기능

기능 설명 목적
트랜잭션 추적 논리 세션을 통해 시간, 순서, 인과관계 등을 추적
일관성 있는 트랜잭션 흐름 유지
재시도 가능한 쓰기 동일 쓰기 요청 중복 처리 방지 (한번만 처리됨)
중복 실행 방지
인과적 일관성 같은 세션에서의 쓰기 후 읽기 시, 쓰기가 반영되어 읽혀짐
순서대로 실행한 연산의 인과관계가 보장됨

 

트랜잭션 API

구분 Core API (Promise 기반) Callback API
개요 비동기 작업을 Promise 또는 async/await으로 처리
비동기 작업 결과를 콜백 함수로 처리
코딩 스타일 현대적인 JavaScript 스타일 (async/await, then)
전통적인 Node.js 스타일 (callback(error, result))
가독성 높음 (코드 흐름이 직관적)
낮음 (콜백 중첩 시 복잡도 증가, "callback hell")
에러 처리 수동 (try/catch 또는 .catch())

오류 처리 통합 안함
- TransientTransactionError,
- UnknownTransactionCommitResult
자동

오류 처리 통합
- 콜백 함수의 첫 번째 인자가 error
적합한 경우 최신 애플리케이션 개발, ES6+ 환경
레거시 코드 유지보수, 콜백 중심의 아키텍처
지원 여부 대부분의 최신 MongoDB 드라이버에서 지원
모든 MongoDB 드라이버에서 지원

 

예제) Core API

더보기
// 세션 시작
const session = db.getMongo().startSession()

// 세션 전용 DB 핸들 얻기
const sessionDb = session.getDatabase("test") // ← 여기 "test"는 실제 Atlas의 DB명으로 교체

try {
  // 트랜잭션 시작
  session.startTransaction()

  // 트랜잭션 내에서 실행할 작업
  sessionDb.restaurants.updateOne(
    { name: "Riviera Caterer" },
    {
      $push: {
        grades: {
          date: new Date(),
          grade: "A",
          score: 20
        }
      }
    }
  )

  // 커밋
  session.commitTransaction()
  print("✅ Transaction committed successfully.")
} catch (error) {
  print("❌ Transaction aborted due to error:", error)
  session.abortTransaction()
} finally {
  session.endSession()
}

 

예제) Callback API

더보기
const session = db.getMongo().startSession()

session.withTransaction(() => {
  const sessionDb = session.getDatabase("test") // ← "test"는 실제 DB 이름으로 교체

  sessionDb.restaurants.updateOne(
    { name: "Riviera Caterer" },
    {
      $push: {
        grades: {
          date: new Date(),
          grade: "B",
          score: 18
        }
      }
    }
  )
}, {
  readConcern: { level: "local" },
  writeConcern: { w: "majority" },
  readPreference: "primary"
})

session.endSession()

 

3. 애플리케이션을 위한 트랜잭션 제한 조정

트랜잭션 시간 제한

항목 항목 설명 기본값 적용 대상
실행시간
transactionLifetimeLimitSeconds 트랜잭션 전체 실행 제한 시간 60초 모든 노드
session.maxTimeMS()
세션 요청당 최대 시간 설정
없음
클라이언트 API 수준
락 대기 maxTransactionLockRequestTimeoutMillis 트랜잭션 락 최대 대기 시간 5ms
서버

 

Oplog 제한

  • 트랜잭션의 쓰기 작업은 MongoDB oplog에 기록됨 (쓰기 작업에 필요한 만큼 oplog 생성)
  • oplog의 크기제한은 BSON 도큐먼트 크기 제한과 동일함 (16MB)