문서 메뉴
문서 홈
/
MongoDB 매뉴얼

트랜잭션

이 페이지의 내용

  • 트랜잭션 API
  • 트랜잭션 및 원자성
  • 트랜잭션 및 작업
  • 트랜잭션 및 세션
  • 읽기 고려/쓰기 고려/읽기 설정
  • 일반 정보
  • 자세히 알아보기

MongoDB에서 단일 문서에 대한 작업은 원자적으로 이루어집니다. 임베디드 문서와 배열을 사용하면 여러 문서와 컬렉션에 걸쳐 정규화하는 대신 단일 문서 구조에서 데이터 간의 관계를 캡처할 수 있으므로 이러한 단일 문서 원자성은 많은 실제 사용 사례에서 분산 트랜잭션의 필요성을 없애줍니다.

여러 문서 (단일 또는 여러 컬렉션)에 대한 읽기 및 쓰기의 원자성이 필요한 상황의 경우, MongoDB는 분산 트랜잭션을 지원합니다. 분산 트랜잭션을 사용하면 여러 작업, 컬렉션, 데이터베이스, 문서 및 샤드에서 트랜잭션을 사용할 수 있습니다.


➤ 오른쪽 위에 있는 언어 선택 드롭다운 메뉴를 사용하여 다음 예제의 언어를 설정하세요.


다음도 참조하세요.

mongosh 의 예시는 mongosh 예시를 참조하세요.

여러 문서(단일 또는 여러 컬렉션)에 대한 읽기 및 쓰기의 원자성이 필요한 상황의 경우, 복제본 세트 및 샤드 클러스터에서의 트랜잭션을 포함한 분산 트랜잭션을 지원합니다.

분산 트랜잭션은 다음과 같이 원자적입니다.

  • 트랜잭션은 모든 데이터 변경 사항을 적용하거나 변경 사항을 롤백합니다.

  • 트랜잭션이 커밋되면 트랜잭션에서 이루어진 모든 데이터 변경 사항이 저장되고 트랜잭션 외부에서 볼 수 있습니다.

    트랜잭션이 커밋될 때까지 트랜잭션에서 변경된 데이터는 트랜잭션 외부에 표시되지 않습니다.

    그러나 트랜잭션이 여러 샤드에 쓰기를 수행하는 경우, 모든 외부 읽기 작업이 커밋된 트랜잭션의 결과가 샤드 전체에 표시될 때까지 기다릴 필요는 없습니다. 예를 들어, 트랜잭션이 커밋되고 쓰기 1이 샤드 A에 표시되지만 쓰기 2가 샤드 B에 아직 표시되지 않는 경우, 읽기 고려 "local"의 외부 읽기는 쓰기 2를 보지 않고 쓰기 1의 결과를 읽을 수 있습니다.

  • 트랜잭션이 중단되면 트랜잭션에서 발생한 모든 데이터 변경 사항은 표시되지 않고 삭제됩니다. 예를 들어, 트랜잭션의 작업이 실패하면 트랜잭션이 중단되고 트랜잭션의 모든 데이터 변경 사항이 표시되지 않은 채로 폐기됩니다.

중요

대부분의 경우 분산 트랜잭션은 단일 문서 쓰기에 비해 더 큰 성능 비용이 발생하므로 분산 트랜잭션의 가용성이 효과적인 스키마 설계를 대체할 수는 없습니다. 대부분의 시나리오에서 비정규화된 데이터 모델 (내장된 문서 및 배열) 은 계속해서 데이터 및 사용 사례에 최적일 것입니다. 즉, 대부분의 시나리오에서 데이터를 적절하게 모델링하면 분산 트랜잭션의 필요성이 최소화됩니다.

추가 트랜잭션 사용 고려 사항(예: 런타임 제한 및 oplog 크기 제한)은 프로덕션 고려사항을 참조하세요.

다음도 참조하세요.

분산 트랜잭션은 여러 작업, 컬렉션, 데이터베이스, 문서 및 샤드 전반에 걸쳐 사용될 수 있습니다.

거래의 경우:

  • 트랜잭션에서 컬렉션과 인덱스를 생성할 수 있습니다. 자세한 내용 은 트랜잭션에서 컬렉션 및 인덱스 만들기를 참조하세요.

  • 트랜잭션에 사용되는 컬렉션은 서로 다른 데이터베이스에 있을 수 있습니다.

    참고

    샤드 간 쓰기 트랜잭션에서는 새 컬렉션을 생성할 수 없습니다. 예를 들어, 하나의 샤드에서 기존 컬렉션에 쓰고 다른 샤드에서 암시적으로 새 컬렉션을 생성하는 경우, MongoDB는 동일한 트랜잭션에서 두 작업을 모두 수행할 수 없습니다.

  • 제한된 컬렉션에는 쓸 (write) 수 없습니다.

  • 고정 사이즈 컬렉션에서 읽을 때는 읽기 고려 "snapshot"을 사용할 수 없습니다. (MongoDB 5.0부터 도입됨)

  • config, admin 또는 local 데이터베이스의 컬렉션을 읽고 쓸 수 없습니다.

  • system.* 컬렉션에 쓸 수 없습니다.

  • explain 또는 이와 유사한 명령을 사용하여 지원되는 작업의 쿼리 계획을 반환할 수 없습니다.

  • 트랜잭션 외부에서 생성된 커서의 경우 트랜잭션 내부에서 getMore을(를) 호출할 수 없습니다.

  • 트랜잭션에서 생성된 커서의 경우 트랜잭션 외부에서 getMore를 호출할 수 없습니다.

  • 트랜잭션 의 첫 번째 작업으로 killCursors지정할 수 없습니다.

트랜잭션에서 지원되지 않는 작업 목록은 제한된 작업을 참조하세요.

트랜잭션을 시작하기 직전에 컬렉션을 만들거나 삭제할 때 트랜잭션 내에서 컬렉션에 액세스하는 경우 쓰기 고려 "majority"가 있는 만들기 또는 삭제 작업을 실행하여 트랜잭션이 필요한 잠금을 획득할 수 있도록 하세요.

다음도 참조하세요.

트랜잭션이 교차 샤드 쓰기 트랜잭션(write transaction)이 아닌 경우 분산 트랜잭션에서 다음 작업을 수행할 수 있습니다.

  • 컬렉션을 생성합니다.

  • 동일한 트랜잭션에서 이전에 생성된 새로운 빈 컬렉션에 인덱스를 생성.

트랜잭션 내에서 컬렉션을 만들 때

트랜잭션 내부에 인덱스를 생성 할 때 [1], 생성할 인덱스는 둘 중 하나에 있어야 합니다.

  • 존재하지 않는 컬렉션입니다. 컬렉션은 작업의 일부로 생성됩니다.

  • 동일한 트랜잭션에서 이전에 생성된 새 빈 컬렉션입니다.

[1] 기존 인덱스에서 db.collection.createIndex()db.collection.createIndexes() 실행하여 존재 여부를 확인할 수도 있습니다. 이러한 작업은 인덱스를 생성하지 않고 성공적으로 반환됩니다.
  • 샤드 간 쓰기 트랜잭션에서는 새 컬렉션을 생성할 수 없습니다. 예를 들어, 하나의 샤드에서 기존 컬렉션에 쓰고 다른 샤드에서 암시적으로 새 컬렉션을 생성하는 경우, MongoDB는 동일한 트랜잭션에서 두 작업을 모두 수행할 수 없습니다.

  • 샤딩된 컬렉션을 대상으로 하는 동안 트랜잭션 내에서 $graphLookup 단계를 사용할 수 없습니다.

  • 트랜잭션 내에서 컬렉션이나 인덱스를 명시적으로 만들려면 트랜잭션 읽기 고려 수준이 "local"여야 합니다.

    컬렉션 및 인덱스를 명시적으로 생성하려면 다음 명령과 메서드를 사용합니다.

    명령
    메서드
    create

다음도 참조하세요.

트랜잭션 내에서 카운트 연산을 수행하려면 $count 집계 단계 또는 $group($sum 표현식 포함) 집계 단계를 사용합니다.

MongoDB 드라이버는 $sum 표현식과 함께 $group를 사용하여 카운트를 수행하는 헬퍼 메서드로서 컬렉션 수준 API countDocuments(filter, options)을 제공합니다. count() API는 더 이상 사용되지 않습니다.

mongoshdb.collection.countDocuments() 표현식과 함께 를 사용하여 $group $sum 카운트를 수행하는 헬퍼 메서드를 제공합니다.

트랜잭션 내에서 고유한 작업을 수행합니다.

  • 샤드되지 않은 컬렉션의 경우, db.collection.distinct() 메서드/distinct 명령과 $group 단계의 aggregation pipeline을 사용할 수 있습니다.리

  • 샤드된 컬렉션의 경우 db.collection.distinct() 메서드 또는 distinct 명령을 사용할 수 없습니다.

    샤딩된 컬렉션의 고유 값을 찾으려면 대신 $group 단계의 집계 파이프라인을 사용합니다. 예를 들면 다음과 같습니다.

    • db.coll.distinct("x")0} 대신 다음을 사용합니다.

      db.coll.aggregate([
      { $group: { _id: null, distinctValues: { $addToSet: "$x" } } },
      { $project: { _id: 0 } }
      ])
    • db.coll.distinct("x", { status: "A" })0} 대신 다음을 사용합니다.

      db.coll.aggregate([
      { $match: { status: "A" } },
      { $group: { _id: null, distinctValues: { $addToSet: "$x" } } },
      { $project: { _id: 0 } }
      ])

    파이프라인은 문서에 커서를 반환합니다.

    { "distinctValues" : [ 2, 3, 1 ] }

    커서를 반복하여 결과 문서에 액세스합니다.

2} buildInfo,helloconnectionStatus , 과 같은 정보 명령(및 그 도우미 메서드) (및 해당 헬퍼 메서드)와 같은 정보 명령은 트랜잭션에서 허용되지만, 트랜잭션의 첫 번째 연산이 될 수는 없습니다.

트랜잭션에서 허용되지 않는 작업은 다음과 같습니다.

  • 트랜잭션은 세션과 관련이 있습니다.

  • 세션당 한 번에 최대 한 개의 열린 트랜잭션만 진행할 수 있습니다.

  • 드라이버를 사용할 때 트랜잭션의 각 작업은 세션과 연결되어야 합니다. 자세한 내용은 드라이버별 문서를 참조하세요.

  • 세션이 종료되고 열려 있는 트랜잭션이 있는 경우 트랜잭션이 중단됩니다.

트랜잭션의 작업에는 트랜잭션 수준 읽기 기본 설정이 사용됩니다.

드라이버를 사용하면 트랜잭션 시작 시 트랜잭션 수준 읽기 기본 설정을 지정할 수 있습니다.

  • 트랜잭션 수준 읽기 설정이 지정되지 않은 경우 트랜잭션은 세션 수준 읽기 설정을 사용합니다.

  • 트랜잭션 수준 및 세션 수준 읽기 설정이 설정되지 않은 경우 트랜잭션은 클라이언트 수준 읽기 설정을 사용합니다. 기본적으로 클라이언트 수준 읽기 설정은 primary입니다.

읽기 작업이 포함된 분산 트랜잭션 은 읽기 설정 primary 을 사용해야 합니다. 특정 트랜잭션의 모든 작업은 동일한 멤버로 라우팅되어야 합니다.

트랜잭션의 작업은 트랜잭션 수준 읽기 고려 (read concern)를 사용합니다. 즉, 컬렉션 및 데이터베이스 수준에서 설정된 읽기 고려 (read concern)는 트랜잭션 내부에서 무시됩니다.

트랜잭션 시작 시 트랜잭션 수준의 읽기 문제를 설정할 수 있습니다.

  • 트랜잭션 수준 읽기 고려 (read concern)가 설정되지 않은 경우 트랜잭션 수준 읽기 고려는 기본적으로 세션 수준 읽기 고려로 설정됩니다.

  • 트랜잭션 수준 및 세션 수준 읽기 고려 (read concern)가 설정되지 않은 경우, 트랜잭션 수준 읽기 고려 (read concern)는 기본적으로 클라이언트 수준 읽기 고려 (read concern)로 설정됩니다. 기본적으로 클라이언트 수준 읽기 고려 (read concern)는 프라이머리 읽기에서 "local"입니다. 다음도 참조하세요.

트랜잭션은 다음과 같은 읽기 고려 수준을 지원합니다.

  • 읽기 고려 "local"는 노드에서 사용 가능한 가장 최근 데이터를 반환하지만 롤백할 수 있습니다.

  • 샤드 클러스터의 트랜잭션의 경우, "local" 읽기 고려는 데이터가 샤드 전체에서 동일한 스냅샷 보기에 속한다고 보장할 수 없습니다. 스냅샷 격리가 필요한 경우 "snapshot" 읽기 고려를 사용하세요.

  • 트랜잭션 내에서 컬렉션과 인덱스를 만들 수 있습니다. 컬렉션이나 인덱스를 명시적으로 생성하는 경우 트랜잭션은 읽기 고려 "local" 를 사용해야 합니다. 컬렉션을 암시적 으로 생성하는 경우 트랜잭션에 사용 가능한 읽기 고려를 사용할 수 있습니다.

  • 트랜잭션이 쓰기 고려 "majority" 로 커밋되면 읽기 고려 "majority" 는 복제본 세트 구성원의 과반수가 승인한 데이터를 반환하며, 이 데이터는 롤백할 수 없습니다. 그렇지 않으면 읽기 고려 "majority" 는 읽기 작업이 과반수가 커밋된 데이터를 읽는다는 보장을 제공하지 않습니다.

  • 샤드 클러스터의 트랜잭션의 경우, 읽기 고려 "majority" 는 샤드 전체에서 동일한 스냅샷 뷰의 데이터임을 보장할 수 없습니다. 스냅샷 격리가 필요한 경우 읽기 고려 "snapshot" 를 사용합니다.

  • 읽기 "snapshot" 고려 는 트랜잭션이 쓰기 고려 "majority"로 커밋된 경우 커밋된 과반수 데이터의 스냅샷에서 데이터를 반환합니다.

  • 트랜잭션이 커밋에 대해 쓰기 고려 'majority' 를 사용하지 않는 경우 "snapshot" 읽기 고려는 읽기 작업이 과반수 커밋 데이터의 스냅샷을 사용했다는 보장을 제공 하지 않습니다 .

  • 샤드 클러스터의 트랜잭션의 경우, 데이터의 "snapshot" 보기가 샤드 간에 동기화됩니다.

트랜잭션은 트랜잭션 수준 쓰기 고려 (write concern)를 사용하여 쓰기 (write) 작업을 커밋합니다. 트랜잭션 내부의 쓰기 (write) 작업은 명시적인 쓰기 고려 (write concern) 지정 없이 실행되어야 하며 기본값 쓰기 고려 (write concern)를 사용해야 합니다. 커밋 시 트랜잭션 수준 쓰기 고려 (write concern)를 사용하여 쓰기 (write)가 커밋됩니다.

트랜잭션 내부의 개별 쓰기 (write) 작업에 대한 쓰기 고려 (write concern)를 명시적으로 설정하지 마세요. 트랜잭션 내부의 개별 쓰기 (write) 작업에 대한 쓰기 고려 (write concern)를 설정하면 오류가 반환됩니다.

트랜잭션 시작 시 트랜잭션 수준 쓰기 문제를 설정할 수 있습니다.

  • 트랜잭션 수준 쓰기 고려 (write concern)가 설정되지 않은 경우, 트랜잭션 수준 쓰기 고려는 커밋에 대한 세션 수준 쓰기 고려를 기본값으로 사용합니다.

  • 트랜잭션 수준 쓰기 고려 (write concern)와 세션 수준 쓰기 고려가 설정되지 않은 경우 트랜잭션 수준 쓰기 고려는 기클라이언트 수준 쓰기 고려를 기본값으로 사용합니다.

트랜잭션은 다음을 포함한 모든 쓰기 고려 w 값을 지원합니다.

  • 쓰기 고려 w: 1은 커밋이 프라이머리에 적용된 후 승인을 반환합니다.

    중요

    w: 1로 커밋할 때 페일오버가 있는 경우 트랜잭션을 롤백할 수 있습니다.

  • w: 1 쓰기 고려로 "majority" 커밋하는 경우 트랜잭션 수준 읽기 고려는 트랜잭션의 읽기 작업이 대다수 커밋된 데이터를 읽지 않는다는 보장을 제공하지 않습니다.

  • w: 1 쓰기 고려로 커밋하는 경우 트랜잭션 수준 "snapshot" 읽기 고려는 트랜잭션의 읽기 작업이 대다수 커밋된 데이터의 스냅샷을 사용했다는 보장을 제공하지 않습니다.

  • 쓰기 고려 w: "majority"는 투표 노드 과반수에게 커밋이 적용된 후 승인을 반환합니다.

  • w: "majority" 쓰기 고려로 커밋하는 경우 트랜잭션 수준 "majority" 읽기 고려는 작업이 대다수 커밋된 데이터를 읽었음을 보장합니다. 샤딩된 클러스터의 트랜잭션의 경우 대부분 커밋된 데이터에 대한 이 보기는 샤드 전체에서 동기화되지 않습니다.

  • w: "majority" 2} 쓰기 고려로 커밋할 때 트랜잭션 수준 "snapshot" 읽기 고려는 작업이 대다수 커밋된 데이터의 동기화된 스냅샷에서 읽은 것을 보장합니다.

참고

트랜잭션에 지정된 쓰기 고려와 관계없이, 샤드 클러스터 트랜잭션에 대한 커밋 작업에는 {w: "majority", j: true} 쓰기 고려를 사용하는 일부 부분이 포함됩니다.

서버 매개변수 coordinateCommitReturnImmediatelyAfterPersistingDecision 트랜잭션 커밋 결정이 클라이언트에 반환되는 시기를 제어합니다.

이 매개 변수는 MongDB 5.0에서 기본값이 true로 도입되었습니다. MongoDB 6.1에서는 기본값이 false로 변경됩니다.

coordinateCommitReturnImmediatelyAfterPersistingDecisionfalse가 되면 샤드 트랜잭션 코디네이터는 모든 멤버가 다중 문서 트랜잭션 커밋을 승인할 때까지 기다린 다음 커밋 결정을 클라이언트에 반환합니다.

다중 문서 "majority" 트랜잭션 에 쓰기 고려를 지정하고 트랜잭션이 복제본 세트 멤버의 계산된 과반수 에 복제되지 못할 경우 트랜잭션이 복제본 세트 멤버에서 즉시 롤백되지 않을 수 있습니다. 복제본 세트는 최종적으로 일관성을 갖 습니다. 트랜잭션은 항상 모든 복제본 세트 멤버에 적용되거나 롤백됩니다.

트랜잭션에 지정된 쓰기 고려 와 관계없이 드라이버는commitTransaction를 다시 시도할 때 쓰기 고려로 w: "majority" 를 적용 .

다음 섹션에서는 트랜잭션에 대한 추가 고려 사항을 설명합니다.

프로덕션 환경에서의 트랜잭션에 대해서는 프로덕션 고려 사항을 참조하세요. 또한 샤드 클러스터의 경우 프로덕션 고려 사항(샤드 클러스터)을 참조하세요.

쓰기 작업이 여러 샤드에 걸쳐 있는 트랜잭션은 트랜잭션 작업 중 어떤 것이든 중재자가 포함된 샤드에서 읽거나 쓰는 경우 오류를 발생시키고 중단됩니다.

writeConcernMajorityJournalDefaultfalse로 설정된 샤드가 있는 샤딩된 클러스터에서는 트랜잭션을 실행할 수 없습니다. (예: 인메모리 스토리지 엔진을 사용하는 투표 멤버가 있는 샤드)

참고

트랜잭션에 지정된 쓰기 고려와 관계없이, 샤드 클러스터 트랜잭션에 대한 커밋 작업에는 {w: "majority", j: true} 쓰기 고려를 사용하는 일부 부분이 포함됩니다.

트랜잭션 상태 및 지표를 얻으려면 다음 메서드를 사용하세요.

소스
반환
트랜잭션 측정항목을 반환합니다.
$currentOp Aggregation pipeline

반환합니다:

db.currentOp() 메서드
currentOp 명령

반환합니다:

mongodmongos 로그 메시지
TXN 로그 구성 요소에 느린 트랜잭션(operationProfiling.slowOpThresholdMs 임계값을 초과하는 트랜잭션)에 대한 정보를 포함합니다.

트랜잭션을 사용하려면 디플로이먼트의 모든 멤버에 대한 FeatureCompatibilityVersion이 최소한 다음과 같아야 합니다.

배포
최소 featureCompatibilityVersion
복제본 세트
4.0
샤딩된 클러스터
4.2

멤버의 fCV를 확인하려면 해당 멤버에 연결하고 다음 명령을 실행하세요.

db.adminCommand( { getParameter: 1, featureCompatibilityVersion: 1 } )

자세한 내용은 setFeatureCompatibilityVersion 도움말 페이지를 참조하세요.

분산 트랜잭션 은 복제본 세트 및 샤드 클러스터에서 지원됩니다.

  • 프라이머리는 WiredTiger 스토리지 엔진을 사용합니다.

  • 보조 멤버는 와이어드타이거 스토리지 엔진 또는 인메모리 스토리지 엔진을 사용합니다.

참고

writeConcernMajorityJournalDefaultfalse으로 설정된 샤드가 있는 샤드 클러스터 (예: 인메모리 스토리지 엔진을 사용하는 투표 멤버가 있는 샤드)에서는 트랜잭션을 실행할 수 없습니다.

MongoDB 5.2(및 5.0.4)부터 시작됩니다.

← update 이벤트