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

트랜잭션

이 페이지의 내용

  • 개요
  • 트랜잭션 API
  • Core API
  • 편리한 트랜잭션 API
  • 트랜잭션 옵션
  • 트랜잭션 오류

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

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

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

참고

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

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

MongoDB에서 다중 문서 트랜잭션은 클라이언트 세션 내에서 실행됩니다. 클라이언트 세션은 순차적으로 실행하고자 하는 관련 읽기 또는 쓰기 작업을 그룹화한 것입니다. 매번 새 클라이언트를 인스턴스화하는 대신 여러 세션 및 트랜잭션에 클라이언트를 재사용할 것을 권장합니다.

majority 읽기 및 쓰기 고려와 결합하면 드라이버는 작업 간의 인과적 일관성을 보장합니다. 자세한 내용은 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 });

이 를 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);

Core API를 사용하여 트랜잭션을 수행하는 경우 다음과 같은 오류에 대한 오류 처리 로직을 애플리케이션에 통합해야 합니다.

  • TransientTransactionError: 드라이버가 트랜잭션을 커밋하기 전에 쓰기 작업에 오류가 발생하면 발생합니다. 이 오류에 대한 자세한 내용은 서버 매뉴얼의 드라이버 API 페이지에서 TransientTransactionError 설명을 참조하세요.

  • UnknownTransactionCommitResult: 커밋 작업에 오류가 나면 발생합니다. 이 오류에 대한 자세한 내용은 서버 매뉴얼의 드라이버 API 페이지에서 UnknownTransactionCommitResult 설명을 참조하세요.

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

돌아가기

집계