Docs Menu
Docs Home
/ / /
Node.js 드라이버
/

트랜잭션

이 가이드에서는 Node.js 드라이버를 사용하여 트랜잭션을 수행하는 방법을 배울 수 있습니다. 트랜잭션을 사용하면 전체 트랜잭션이 커밋될 때까지 데이터를 변경하지 않는 일련의 작업을 실행할 수 있습니다. 트랜잭션에서 작업이 실패하는 경우 드라이버는 트랜잭션을 종료하고 데이터 변경 사항이 표시되기 전에 모든 데이터 변경 사항을 삭제합니다. 이 특성을 원자성이라고 합니다.

MongoDB의 단일 문서에 대한 모든 쓰기 작업은 개별적으로 이뤄지므로 트랜잭션을 사용하여 여러 문서를 수정하는 원자(atomic) 변경을 수행해야 할 수 있습니다. 이 경우 다중 문서 트랜잭션이 필요합니다. MongoDB는 드라이버에 예기치 않은 오류가 발생하더라도 트랜잭션 작업과 관련된 데이터가 일관성을 유지하도록 보장하기 때문에 다중 문서 트랜잭션은 ACID를 준수합니다.

ACID 컴플라이언스 및 트랜잭션에 대한 자세한 내용은 ACID 트랜잭션 관련 문서를 참조하세요.

참고

다중 문서 트랜잭션을 실행하려면 MongoDB Server 버전 4.0 이상을 실행하는 배포에 연결해야 합니다.

자세한 제한 사항 목록은 Server 매뉴얼의 트랜잭션 및 운영 섹션을 참조하세요.

이 가이드의 다음 섹션에서 드라이버를 사용하여 다중 문서 트랜잭션을 수행하는 방법에 대해 더욱 자세히 알아보세요.

MongoDB 특정 클라이언트 세션에서 인과적 일관성 지원합니다. 인과적 일관성 모델은 분산된 시스템에서 세션 내의 작업이 인과적 순서로 실행 보장 . 클라이언트는 인과 관계 또는 작업 간의 종속성과 일관적인 결과를 관찰합니다. 예시 를 들어, 한 작업이 논리적으로 다른 작업의 결과에 따라 달라지는 일련의 작업을 수행하는 경우 모든 후속 읽기에는 종속 관계 반영됩니다.

인과적 일관성 보장하려면 클라이언트 세션이 다음 요구 사항을 충족해야 합니다.

  • 세션을 시작할 때 운전자 인과적 일관성 옵션을 활성화 해야 합니다. 이 옵션은 기본값 으로 활성화되어 있습니다.

  • 작업은 단일 스레드의 단일 세션에서 실행 되어야 합니다. 그렇지 않으면 세션 또는 스레드가 optime 및 클러스터 시간 값을 서로 통신해야 합니다. 이러한 값을 전달하는 두 세션의 예시 보려면 MongoDB Server 매뉴얼에서 인과적 일관성 예시 를 참조하세요.

  • majority 읽기 고려 (read concern) 사용해야 합니다.

  • 반드시 majority 쓰기 고려 (write concern) 사용해야 합니다. 이는 기본값 쓰기 고려 (write concern) 값입니다.

다음 표에서는 인과적으로 일관적인 세션이 제공하는 보장 에 대해 설명합니다.

보장
설명

쓰기 읽기

읽기 작업은 이전 쓰기 (write) 작업의 결과를 반영합니다.

단조적 읽기

읽기 작업은 이전 읽기 작업보다 이전 데이터 상태 반영하는 결과를 반환하지 않습니다.

단조로운 쓰기

쓰기 (write) 작업이 다른 쓰기 (write) 작업보다 먼저 수행되어야 하는 경우 서버 이 쓰기 (write) 작업을 먼저 실행합니다.

예시 를 들어 insertOne() 를 호출하여 문서 삽입한 다음 updateOne() 를 호출하여 삽입된 문서 수정하면 서버 먼저 삽입 작업을 실행합니다.

읽기 후 쓰기

쓰기 (write) 작업이 다른 읽기 작업 뒤에 와야 하는 경우 서버 읽기 작업을 먼저 실행합니다.

예시 를 들어 findOne() 를 호출하여 문서 조회 다음 deleteOne() 를 호출하여 조회된 문서 삭제 하면 서버 먼저 찾기 작업을 실행합니다.

이 섹션에 언급된 개념에 대해 자세히 학습 다음 MongoDB Server 매뉴얼 항목을 참조하세요.

이 드라이버는 트랜잭션 수행을 위한 두 가지 API, 즉 Core API편리한 트랜잭션 API를 제공합니다.

Core API는 트랜잭션을 생성, 커밋, 종료할 수 있는 프레임워크입니다. 해당 API를 사용할 때 다음 조치를 명시적으로 수행해야 합니다.

  • 트랜잭션 생성, 커밋, 종료.

  • 트랜잭션을 실행하는 세션 생성 및 종료.

  • 오류 처리 로직 구현.

편리한 트랜잭션 API는 트랜잭션을 커밋하거나 종료할 책임 없이 트랜잭션을 수행할 수 있는 프레임워크입니다. 해당 API는 서버에서 특정 오류 유형이 발생할 때 작업을 다시 시도하는 오류 처리 로직을 자동으로 통합합니다. 이 동작에 대해 자세히 알아보려면 본 가이드의 트랜잭션 오류 섹션을 참조하세요.

중요

MongoDB Server 버전 4.2 이하에 연결하는 경우, 이미 존재하는 컬렉션에 대해서만 트랜잭션에서 쓰기 작업을 수행할 수 있습니다. MongoDB Server 버전 4.4 이상에 연결하면 트랜잭션에서 쓰기 작업을 수행할 때 필요에 따라 서버가 자동으로 컬렉션을 생성합니다. 이 동작에 대한 자세한 내용은 Server 매뉴얼의 트랜잭션 내 컬렉션 및 인덱스 생성을 참조하세요.

Core API는 트랜잭션을 구현하기 위해 다음과 같은 메서드를 제공합니다.

이 API를 사용할 때는 다음 단계를 수행해야 합니다.

  • 세션 인스턴스를 해당 세션에서 실행하려는 각 작업에 전달합니다.

  • 서버 트랜잭션 오류를 식별하고 오류 처리 로직을 구현하는 catch 차단을 구현합니다.

다음 코드는 Core API를 사용하여 트랜잭션을 수행하는 방법을 보여줍니다:

async function coreTest(client) {
const session = client.startSession();
try {
session.startTransaction();
const savingsColl = client.db("bank").collection("savings_accounts");
await savingsColl.findOneAndUpdate(
{account_id: "9876"},
{$inc: {amount: -100 }},
{ session });
const checkingColl = client.db("bank").collection("checking_accounts");
await checkingColl.findOneAndUpdate(
{account_id: "9876"},
{$inc: {amount: 100 }},
{ session });
// ... perform other operations
await session.commitTransaction();
console.log("Transaction committed.");
} catch (error) {
console.log("An error occurred during the transaction:" + error);
await session.abortTransaction();
} finally {
await session.endSession();
}
}

중요

세션을 시작한 클라이언트를 통한 세션 사용

MongoClient 인스턴스에서 다른 클라이언트 인스턴스로 세션을 제공하는 경우 드라이버에서 오류가 발생합니다.

예를 들어 다음 코드는 인스턴스 MongoInvalidArgumentError ClientSession client1 클라이언트에서 인스턴스를 만들지만, client2 쓰기 작업을 위해 이 세션을 클라이언트에 제공하기 때문에 오류가 발생합니다.

const session = client1.startSession();
client2.db('myDB').collection('myColl').insertOne({ name: 'Jane Eyre' }, { session });

명시적 리소스 관리

Node.js 운전자 MongoClient 기본적으로,, 및 커서에 대한 명시적 리소스 관리ClientSession ChangeStreams지원합니다. 이 기능 실험적이며 변경될 수 있습니다. 명시적 리소스 관리 사용하는 방법을 학습 v6.9 릴리스 노트 참조하세요.

이 를 Core API 사용하는 완전히 실행 가능한 API 예시 를 보려면 사용 예시 사용을 참조하세요.

편리한 트랜잭션 API는 트랜잭션을 구현하기 위해 다음과 같은 방법을 제공합니다.

  • withSession(): 세션 내에서 전달된 콜백을 실행합니다. API는 세션의 생성 및 종료를 자동으로 처리합니다.

  • withTransaction(): 트랜잭션 내에서 전달된 콜백을 실행하고 콜백이 반환되면 commitTransaction() 메서드를 호출합니다.

이러한 메서드는 콜백이 반환하는 값을 반환합니다. 예를 들어, withTransaction() 메서드에 전달한 콜백이 { hello: "world" } 문서를 반환하면 withTransaction() 메서드도 해당 문서를 반환합니다.

중요

무한 반복 오류를 방지하려면 withTransaction() 메서드에 전달하는 콜백 이 발생하는 오류를 포착하는지 확인하세요.

편리한 트랜잭션 API를 사용하면 콜백의 반환 값을 withTransaction()withSession() 메서드의 반환 값으로 전파하여 코드의 다른 곳에서 사용할 수 있습니다.

이 API를 사용할 때는 다음 단계를 수행해야 합니다.

  • 세션 인스턴스를 해당 세션에서 실행하려는 각 작업에 전달합니다.

  • 세션의 각 작업에 대해 비동기 await 구문을 구현합니다.

  • Promise.all() 메서드 호출과 같은 병렬 처리를 피하세요. 세션을 병렬로 사용하면 일반적으로 서버 오류가 발생합니다.

다음 코드는 편리한 트랜잭션 API를 사용하여 트랜잭션을 수행하는 방법을 보여줍니다.

async function convTest(client) {
let txnRes = await client.withSession(async (session) =>
session.withTransaction(async (session) => {
const savingsColl = client.db("bank").collection("savings_accounts");
await savingsColl.findOneAndUpdate(
{account_id: "9876"},
{$inc: {amount: -100 }},
{ session });
const checkingColl = client.db("bank").collection("checking_accounts");
await checkingColl.findOneAndUpdate(
{account_id: "9876"},
{$inc: {amount: 100 }},
{ session });
// ... perform other operations
return "Transaction committed.";
}, null)
);
console.log(txnRes);
}

해당 API를 사용하는 완전히 실행 가능한 예시를 보려면 편리한 트랜잭션 API 사용 예시를 참조하세요.

참고

병렬 작업이 지원되지 않음

Node.js 드라이버는 단일 트랜잭션 내에서 병렬 작업 실행을 지원하지 않습니다.

TransactionOptions 인스턴스를 startTransaction()withTransaction() 메서드에 전달하여 드라이버가 트랜잭션을 수행하는 방식을 구성할 수 있습니다. 옵션을 지정하면 MongoClient 인스턴스에 기존에 설정된 옵션 값이 재정의됩니다.

다음 표는 TransactionOptions 인스턴스에서 지정할 수 있는 옵션을 포함합니다.

설정
설명

readConcern

Specifies read operation consistency of the replica set.
To learn more, see Read Concern in the Server manual.

writeConcern

Specifies the write operation level of acknowledgment required from a replica set.
To learn more, see Write Concern in the Server manual.

readPreference

Specifies how to route read operations to members of a replica set.
To learn more, see Read Preference in the Server manual.

maxCommitTimeMS

트랜잭션의 커밋 조치가 실행될 수 있는 시간(밀리초)을 지정합니다.

전체 옵션 목록은 트랜잭션 옵션에 대한 API 설명서를 참조하세요.

참고

트랜잭션 옵션에서 설정을 지정하지 않는 한 트랜잭션은 MongoClient 인스턴스의 설정을 상속합니다.

다음 코드는 트랜잭션 옵션을 정의하고 startTransaction() 메서드에 전달하는 방법을 보여줍니다.

const txnOpts = {
readPreference: 'primary',
readConcern: { level: 'local' },
writeConcern: { w: 'majority' },
maxCommitTimeMS: 1000
};
session.startTransaction(txnOpts);

MongoDB 트랜잭션은 ACID 준수하므로 데이터의 일관적인 유지하기 위해 운전자 작동 중에 오류를 발생시킬 수 있습니다. 다음 오류가 발생하면 애플리케이션 트랜잭션 다시 시도해야 합니다.

  • TransientTransactionError: 운전자 트랜잭션 커밋하기 전에 쓰기 (write) 작업에 오류가 발생하면 발생합니다. 이 오류 유형에 대해 자세히 학습하려면 서버 매뉴얼의 드라이버 API 페이지에 있는 TransientTransactionError 설명 을 참조하세요.

  • UnknownTransactionCommitResult: 커밋 작업에 오류가 발생하면 발생합니다. 이 오류 유형에 대해 자세히 학습 서버 매뉴얼의 드라이버 API 페이지에 있는 UnknownTransactionCommitResult 설명을 참조하세요.

다음 섹션에서는 다양한 API를 사용할 때 이러한 오류를 처리하다 방법을 설명합니다.

편리한 트랜잭션 API 이러한 오류 유형에 대한 재시도 로직이 통합되어 있습니다. 운전자 성공적인 커밋 있을 때까지 트랜잭션 자동으로 재시도합니다.

코어 API 사용하여 트랜잭션 수행하는 경우 애플리케이션 에 다음 오류 처리 함수를 추가해야 합니다.

  • 운전자 다음과 같은 경우 전체 트랜잭션 재시도하는 함수입니다. TransientTransactionError

  • 운전자 다음과 같은 경우 커밋 작업을 다시 시도하는 함수입니다. UnknownTransactionCommitResult

이러한 함수는 커밋 성공적인 하거나 다른 오류가 발생할 때까지 실행 되어야 합니다. 이 재시도 로직의 예시 는 서버 매뉴얼의 드라이버 API 페이지에 있는 코어 API 섹션을 참조하세요.

돌아가기

복합 작업

이 페이지의 내용