트랜잭션
개요
이 가이드 에서는 MongoDB C++ 드라이버 를 사용하여 트랜잭션을 수행하는 방법을 학습 수 있습니다. 트랜잭션을 사용하면 트랜잭션 이 커밋될 때까지 데이터를 변경하지 않는 일련의 작업을 실행 수 있습니다. 트랜잭션 에서 오류가 반환되는 경우 운전자 는 트랜잭션 을 취소하고 데이터 변경 사항이 표시되기 전에 모든 데이터 변경 사항을 삭제합니다.
MongoDB 에서 트랜잭션은 논리적 세션 내에서 실행 됩니다. 세션은 순차적으로 실행 하려는 관련 읽기 또는 쓰기 (write) 작업의 그룹입니다. 세션을 활성화 원자성, 일관성, 격리 및 내구성에 대한 기대치를 충족하는 트랜잭션 인 ACID 호환 트랜잭션 에서 작업 그룹 에 대한 인과적 일관성 을 사용할 수 있습니다. MongoDB 는 작업에 예기치 않은 오류가 발생하더라도 트랜잭션 작업과 관련된 데이터가 일관적인 을 유지하도록 보장 합니다.
C++ 운전자 를 사용하는 경우 mongocxx::client
인스턴스 에서 새 세션을 만들 수 있습니다. 그런 다음 결과 mongocxx::client_session
인스턴스 를 사용하여 트랜잭션을 수행할 수 있습니다. 매번 새 클라이언트 를 인스턴스화하는 대신 여러 세션 및 트랜잭션에 클라이언트 를 재사용하는 것이 좋습니다.
경고
mongocxx::client_session
을(를) 생성한 mongocxx::client
에만 사용하세요. 다른 client
와 함께 client_session
를 사용하면 작업 오류가 발생합니다.
중요
의 mongocxx::client
인스턴스는 스레드로부터 안전하지 않습니다.mongoxcc::client
를 포함한 각 인스턴스 와 해당 하위 mongocxx::client_session
인스턴스는 한 번에 단일 스레드에서 사용해야 합니다. 학습 내용은 스레드 및 포크 안전 가이드 를 참조하세요.
트랜잭션 API
MongoDB C++ 드라이버 는 트랜잭션 라이프 스타일을 관리 하기 위해 콜백 API 와 코어 API 를 제공합니다. 트랜잭션 을 시작하기 전에 start_session()
메서드를 호출하여 mongocxx::client_session
을(를) 인스턴스화해야 합니다. 그런 다음 다음 API 중 하나를 사용하여 트랜잭션 을 수행할 수 있습니다.
콜백 API: 트랜잭션 의 라이프사이클을 관리하고 오류 처리 로직을 자동으로 통합하는 고급 API 입니다.
코어 API: 트랜잭션 의 라이프사이클을 관리 하고 사용자 지정 오류 처리 로직을 구현 수 있는 로우 레벨 API 입니다.
팁
오류 처리에 학습 보려면 MongoDB Server 매뉴얼의 트랜잭션 오류 처리 섹션을 참조하세요.
Callback API
콜백 API 를 사용하여 MongoDB C++ 드라이버 가 트랜잭션 의 수명 주기를 관리 있도록 합니다. 이 API 를 구현 하려면 mongocxx::client_session
에서 with_transaction()
메서드를 호출하고 실행 작업 순서를 지정하는 콜백 함수를 전달합니다. with_transaction()
메서드는 트랜잭션 을 시작하고 콜백 함수를 실행하며 트랜잭션 트랜잭션 종료합니다. 트랜잭션 에 TransientTransactionError
또는 UnknownTransactionCommitResult
오류가 발생하면 with_transaction()
메서드가 트랜잭션 을 다시 실행합니다.
다음 코드는 콜백 API 를 사용하여 sample_mflix
데이터베이스 의 movies
및 comments
컬렉션에 문서를 삽입하는 트랜잭션 을 수행합니다. 이 코드는 다음 작업을 수행합니다.
start_session()
메서드를 사용하여 클라이언트 에서 세션을 시작합니다.트랜잭션 중에 수행할 작업을 지정하는 콜백 함수를 정의합니다.
트랜잭션 작업에 대한 쓰기 고려 (write concern) 를 설정하다 하기 위해 준비하는 옵션 객체 를 만듭니다. 읽기 및 쓰기 (write) 시맨틱에 대해 학습 보려면 MongoDB Server 매뉴얼의 읽기 고려/쓰기 고려/읽기 설정 섹션을 참조하세요.
with_transaction()
메서드를 호출하여 트랜잭션 을 관리 하고 콜백 함수와 옵션 객체 를 인수로 전달합니다.
// Establish a connection to the MongoDB deployment mongocxx::instance instance{}; mongocxx::client client(mongocxx::uri{"<connectionString>"}); // Define database and collection variables auto db = client["sample_mflix"]; auto movies_collection = db["movies"]; auto comments_collection = db["comments"]; // Define a callback specifying the sequence of operations to perform during the transaction mongocxx::client_session::with_transaction_cb callback = [&](mongocxx::client_session* session) { // Important:: You must pass the session to the operations. movies_collection.insert_one(*session, make_document(kvp("title", "Parasite"))); comments_collection.insert_one(*session, make_document(kvp("name", "Anjali Patel"), kvp("text", "This is my new favorite movie!"))); }; // Define an options instance to explicitly set the write concern for the transaction operations mongocxx::options::transaction opts; mongocxx::write_concern wc; wc.acknowledge_level(mongocxx::write_concern::level::k_majority); opts.write_concern(wc); // Start a client session auto session = client.start_session(); try { // Start a transaction, execute the operations in the callback function, and commit the results session.with_transaction(callback, opts); } catch (const mongocxx::exception& e) { std::cout << "An exception occurred: " << e.what() << std::endl; return EXIT_FAILURE; } return EXIT_SUCCESS;
Core API
코어 API 를 사용하여 트랜잭션 의 수명 주기를 관리 합니다. 이 API 를 구현 하려면 mongocxx::client_session
인터페이스의 메서드를 명시적으로 호출하여 트랜잭션 을 시작하고, 활성 트랜잭션 을 커밋 하고, 오류가 발생하면 트랜잭션 을 종료해야 합니다. 핵심 API 는 오류 처리 로직을 자동으로 통합하지 않고 대신 TransientTransactionError
및 UnknownTransactionCommitResult
등의 오류에 대한 사용자 지정 처리 로직을 구현 수 있습니다.
다음 표에서는 mongocxx::client_session
인터페이스에서 제공하는 핵심 API 메서드에 대해 설명합니다.
메서드 | 설명 |
---|---|
| Starts a new transaction on the current client session. Accepts an optional mongocxx::options::transaction
instance as an argument to set options. For a full list of options, see mongocxx::options::transaction
in the API documentation.Raises an exception if the options are misconfigured, if there are network or other transient failures, or if there
are other errors such as a session with a transaction already in progress. If an error is returned with the TransientTransactionError label,
you can end the transaction and then retry it with the expectation that it will succeed.To learn more about this method, see the startTransaction() guide in the MongoDB Server manual. |
| Commits the active transaction on the current client session. Raises an exception if options are misconfigured, if there are network or other transient failures,
or if there are other errors such as a session with no transaction in progress. If an error is returned with the UnknownTransactionCommitResult label,
you can end the transaction and then retry it with the expectation that it will succeed when the committed transaction satisfies the set write concern.To learn more about this method, see the commitTransaction() guide in the MongoDB Server manual. |
| Ends the active transaction on the current client session. Raises an exception if the options are misconfigured or if there are other errors such as
a session with no transaction in progress. To learn more about this method, see the abortTransaction() guide in the MongoDB Server manual. |
팁
클래스는 mongocxx::client_session
세션 속성을 조회 하고 수정하는 메서드도 제공합니다. 학습 내용은 API 문서에서 mongocxx::client_session을 참조하세요.
다음 코드는 핵심 API 를 사용하여 sample_mflix
데이터베이스 의 movies
및 comments
컬렉션에 문서를 삽입하는 트랜잭션 을 수행합니다. 이 코드는 다음 작업을 수행합니다.
start_session()
메서드를 사용하여 클라이언트 에서 세션을 시작합니다.트랜잭션 작업에 대한 쓰기 고려 (write concern) 를 설정하다 하기 위해 준비하는 옵션 객체 를 만듭니다. 읽기 및 쓰기 (write) 시맨틱에 대해 학습 보려면 MongoDB Server 매뉴얼의 읽기 고려/쓰기 고려/읽기 설정 섹션을 참조하세요.
start_transaction()
메서드를 호출하여 트랜잭션 을 시작하고 옵션 객체 를 인수로 전달합니다.sample_mflix
데이터베이스 의 컬렉션에 문서를 삽입하는 작업을 실행하여 각 작업에 활성 세션을 전달합니다. 작업에 오류가 발생하면 전체 트랜잭션 이 중단됩니다. 오류에TransientTransactionError
레이블이 있는 경우 트랜잭션 이 재시도됩니다.commit_transaction()
메서드를 사용하여 활성 트랜잭션 을 커밋합니다. 커밋 에UnknownTransactionCommitResult
레이블과 관련된 오류가 발생하면 커밋 이 다시 시도됩니다.
// Establish a connection to the MongoDB deployment mongocxx::instance instance{}; mongocxx::client client(mongocxx::uri{"<connectionString>"}); // Runs the txn_func and retries if TransientTransactionError occurs using transaction_func = std::function<void(mongocxx::client_session& session)>; auto run_with_retry = [](transaction_func txn_func, mongocxx::client_session& session) { while (true) { try { txn_func(session); // performs transaction. break; } catch (const mongocxx::operation_exception& oe) { std::cout << "Transaction aborted. Caught exception during transaction." << std::endl; // If transient error, retry the whole transaction. if (oe.has_error_label("TransientTransactionError")) { std::cout << "TransientTransactionError, retrying transaction..." << std::endl; continue; } else { throw oe; } } } }; // Commits the active transaction and retries commit if UnknownTransactionCommitResult occurs auto commit_with_retry = [](mongocxx::client_session& session) { while (true) { try { session.commit_transaction(); // Uses write concern set at transaction start. std::cout << "Transaction committed." << std::endl; break; } catch (const mongocxx::operation_exception& oe) { // Can retry commit if (oe.has_error_label("UnknownTransactionCommitResult")) { std::cout << "UnknownTransactionCommitResult, retrying commit..." << std::endl; continue; } else { std::cout << "Error during commit..." << std::endl; throw oe; } } } }; auto txn_func = [&](mongocxx::client_session& session) { auto& client = session.client(); // Define database and collection variables auto db = client["sample_mflix"]; auto movies_collection = db["movies"]; auto comments_collection = db["comments"]; // Define an options instance to explicitly set the write concern for the transaction operations mongocxx::options::transaction opts; mongocxx::write_concern wc; wc.acknowledge_level(mongocxx::write_concern::level::k_majority); opts.write_concern(wc); session.start_transaction(opts); // Attempt to insert documents into database collections try { movies_collection.insert_one(session, make_document(kvp("title", "Parasite"))); comments_collection.insert_one(session, make_document(kvp("name", "Anjali Patel"), kvp("text", "This is my new favorite movie!"))); } catch (const mongocxx::operation_exception& oe) { std::cout << "Caught exception during transaction, aborting." << std::endl; session.abort_transaction(); throw oe; } commit_with_retry(session); }; // Start a client session auto session = client.start_session(); try { run_with_retry(txn_func, session); } catch (const mongocxx::operation_exception& oe) { // Do something with error throw oe; }
추가 정보
이 가이드 에 설명된 개념에 대해 학습 보려면 MongoDB Server 매뉴얼의 다음 페이지를 참조하세요.
ACID 에 학습 보려면 MongoDB 웹사이트 에서 데이터베이스 관리 시스템의 ACID 속성 가이드 를 참조하세요.
삽입 작업에 대해 자세히 알아보려면 문서 삽입 가이드를 참조하세요.
API 문서
이 가이드에서 설명하는 유형 또는 메서드에 대해 자세히 알아보려면 다음 API 문서를 참조하세요.