트랜잭션 및 세션
개요
이 가이드 에서는 Mongoid를 사용하여 트랜잭션을 수행하는 방법을 학습 수 있습니다. 트랜잭션을 사용하면 전체 트랜잭션 이 커밋된 경우에만 데이터를 변경하는 일련의 작업을 수행할 수 있습니다. 트랜잭션 의 작업이 성공하지 못하면 운전자 트랜잭션 중지하고 데이터 변경 사항이 표시되기 전에 모든 데이터 변경 사항을 삭제합니다. 이 기능 원자성이라고 합니다.
MongoDB 에서 트랜잭션은 논리적 세션 내에서 실행 . 세션은 순차적으로 실행 하려는 관련 읽기 또는 쓰기 (write) 작업의 그룹입니다. 세션을 사용하면 작업 그룹 에 대해 인과적 일관성 활성화 있으므로 애플리케이션 의 모든 프로세스가 인과적으로 관련된 작업의 순서에 동의합니다.
세션을 사용하면 원자성, 일관성, 격리 및 내구성 기대치를 충족하는 ACID 호환 트랜잭션 에서 작업을 실행 수 있습니다. MongoDB 작업에 예기치 않은 오류가 발생하더라도 트랜잭션 작업과 관련된 데이터가 일관적인 유지하도록 보장 .
Mongoid에서는 다음 API 중 하나를 사용하여 트랜잭션을 수행할 수 있습니다.
고급 트랜잭션 API: Mongoid는 트랜잭션 의 라이프사이클을 관리합니다. 이 API Mongoid v9.0 이상에서 사용할 수 있습니다.
로우 레벨 트랜잭션 API: 트랜잭션 의 라이프사이클을 관리 해야 합니다. 이 API Mongoid v6.4 이상에서 사용할 수 있습니다.
세션 API 섹션에서는 트랜잭션 수행하지 않고 세션 내에서 데이터를 변경하는 방법을 설명합니다.
고급 트랜잭션 API
고급 트랜잭션 API 사용하여 트랜잭션 의 수명 주기를 내부적으로 관리 수 있습니다. 이 API 트랜잭션 커밋하거나 종료하고 오류 처리 로직을 통합합니다.
모델의 인스턴스 , 모델 클래스 또는 Mongoid
모듈에서 transaction
메서드를 호출하여 트랜잭션 시작할 수 있습니다.
transaction
메서드를 호출하면 Mongoid가 다음 작업을 수행합니다.
클라이언트 에 세션을 만듭니다.
세션에서 트랜잭션 시작합니다.
지정된 데이터 변경을 수행합니다.
오류가 발생하지 않으면 트랜잭션 데이터베이스 에 커밋하고, 오류가 발생하면 트랜잭션 종료합니다.
세션을 닫습니다.
트랜잭션 이 커밋되면 Mongoid는 트랜잭션 내부에서 수정된 모든 객체에 대해 after_commit
콜백을 호출합니다. 오류가 발생하여 트랜잭션 이 롤백되면 Mongoid는 트랜잭션 내부에서 수정된 모든 객체에 대해 after_rollback
콜백을 호출합니다. 이러한 콜백과 그 동작에 대해 자세히 학습 이 가이드 의 콜백 섹션을 참조하세요.
예시
이 예시 다음 모델을 사용하여 책과 영화를 설명하는 문서를 나타냅니다.
class Book include Mongoid::Document field :title, type: String field :author, type: String field :length, type: Integer end class Film include Mongoid::Document field :title, type: String field :year, type: Integer end
다음 코드는 서로 다른 객체에 대해 트랜잭션 수행하여 여러 컬렉션의 데이터를 변경하는 방법을 보여 줍니다.
# Starts a transaction from the model class Book.transaction do # Saves new Book and Film instances to MongoDB Book.create(title: 'Covert Joy', author: 'Clarice Lispector') Film.create(title: 'Nostalgia', year: 1983) end # Starts a transaction from an instance of Book book = Book.create(title: 'Sula', author: 'Toni Morrison') book.transaction do # Saves a new field value to the Book instance book.length = 192 book.save! end # Starts a transaction from the Mongoid instance Mongoid.transaction do # Deletes the Book instance in MongoDB book.destroy end
클라이언트 동작
각 트랜잭션 특정 클라이언트 에 연결되므로 동일한 클라이언트 에 대한 작업만 트랜잭션 범위에 속합니다. 트랜잭션 메서드 차단 내에서 동일한 클라이언트 의 객체를 사용해야 합니다.
다음 예시 다양한 클라이언트를 사용하는 모델 클래스를 정의하고 원본 클라이언트 기반으로 작업이 실행 되는 방법을 보여 줍니다.
# Defines a class by using the :default client class Post include Mongoid::Document end # Defines a class by using the :encrypted_client class User include Mongoid::Document store_in client: :encrypted_client end # Starts a transaction on the :encrypted_client User.transaction do # Uses the same client, so the operation is in the transaction User.create! # Uses a different client, so it is *not* in the transaction Post.create! end
참고
Mongoid
모듈에서 transaction
메서드를 호출하면 Mongoid는 :default
클라이언트 사용하여 트랜잭션 생성합니다.
트랜잭션 종료
트랜잭션 메서드 차단 내에서 예외가 발생하면 트랜잭션 종료되고 데이터 변경 사항이 롤백됩니다. Mongoid는 Mongoid::Errors::Rollback
예외를 제외한 모든 예외를 표시합니다. 애플리케이션 에서 이 예외를 발생시켜 예외를 반환하지 않고 트랜잭션 명시적으로 종료할 수 있습니다. 예시 를 들어, 특정 조건이 충족되지 않지만 예외 메시지를 발생시키지 않고 트랜잭션 종료하기 위해 이 트랜잭션 예외를 구현 수 있습니다.
콜백
이 트랜잭션 API after_commit
및 after_rollback
콜백을 도입합니다.
Mongoid는 다음과 같은 경우에 생성, 저장 또는 삭제된 객체 에 대해 after_commit
콜백 트리거합니다.
트랜잭션 내부에서 객체 수정된 경우 트랜잭션 이 커밋된 후입니다.
객체 객체 트랜잭션 차단 외부에서 수정된 경우 객체 가 유지된 후.
after_commit
콜백 다른 모든 콜백이 성공적으로 수행된 후에만 트리거됩니다. 따라서 객체 트랜잭션 외부에서 수정되면 객체 가 유지되지만 after_commit
콜백 트리거되지 않을 수 있습니다. 예시 들어 after_commit
를 트리거하다 하려면 이 콜백 성공적으로 완료되어야 하기 때문에 Mongoid가 after_save
콜백 에서 예외를 발생시킨 경우 이러한 상황이 발생할 수 있습니다.
트랜잭션 실패하고 변경 사항이 롤백된 경우 트랜잭션 내에서 생성, 저장 또는 삭제된 객체 에 대해 after_rollback
콜백 트리거됩니다. Mongoid는 트랜잭션 외부에서 after_rollback
을(를) 트리거하지 않습니다.
콜백에 대해 자세히 학습 데이터 모델용 콜백 사용자 지정 가이드 참조하세요.
로우 레벨 트랜잭션 API
하위 수준 API 사용하는 경우 트랜잭션 시작하기 전에 세션을 만들어야 합니다. 모델 클래스 또는 모델의 인스턴스 에서 with_session
메서드를 호출하여 세션을 만들 수 있습니다.
그런 다음 세션에서 start_transaction
메서드를 호출하여 트랜잭션 시작할 수 있습니다. 이 API 사용할 때는 트랜잭션 수동으로 커밋 하거나 종료해야 합니다. 세션 인스턴스 에서 commit_transaction
및 abort_transaction
메서드를 사용하여 트랜잭션 수명 주기를 관리 수 있습니다.
예시
이 예시 하위 수준 트랜잭션 API 사용하여 다음 작업을 수행합니다.
세션을 생성합니다.
트랜잭션을 시작합니다.
데이터 작업 수행
트랜잭션 커밋하거나 오류가 있는 경우 종료합니다.
# Starts a session from the model class Book.with_session do |session| session.start_transaction # Creates a Book Book.create(title: 'Siddhartha', author: 'Hermann Hesse') # Commits the transaction session.commit_transaction rescue StandardError # Ends the transaction if there is an error session.abort_transaction end
참고
세션이 종료되고 열린 트랜잭션 포함되면 트랜잭션 이 자동으로 종료됩니다.
트랜잭션 재시도
트랜잭션 커밋 처음에 실패하면 다시 시도할 수 있습니다. 다음 예시 Mongoid가 UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL
예외를 발생시킬 때 트랜잭션 재시도하는 방법을 보여줍니다.
begin session.commit_transaction rescue Mongo::Error => e if e.label?(Mongo::Error::UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL) retry else raise end end
옵션
start_transaction
메서드에 옵션을 전달하여 트랜잭션 시작할 때 읽기 고려 (read concern), 쓰기 고려 (write concern) 또는 읽기 설정 (read preference) 지정할 수 있습니다.
session.start_transaction( read_concern: {level: :majority}, write_concern: {w: 3}, read: {mode: :primary} )
사용 가능한 트랜잭션 옵션에 대해 자세히 학습 Ruby 운전자 API 문서에서 start_transaction을 참조하세요.
클라이언트 동작
트랜잭션 내에서 작업을 수행하려면 작업에서 세션이 시작된 것과 동일한 클라이언트 사용해야 합니다. 기본값 으로 모든 작업은 기본값 클라이언트 사용하여 수행됩니다.
다른 클라이언트 를 명시적으로 사용하려면 with
메서드를 사용합니다.
# Specifies that the operation should use the "other" client instead of # the default client User.with(client: :other) do Post.with(client: :other) do Post.with_session do |session| session.start_transaction Post.create! Post.create! User.create! session.commit_transaction end end end
Session API
트랜잭션 수행하는 것과 비슷한 방식으로 Mongoid에서 세션을 사용할 수 있습니다. 모델 클래스 또는 모델의 인스턴스 에서 with_session
메서드를 호출하고 차단 에서 일부 작업을 수행할 수 있습니다. 차단 의 모든 작업은 단일 세션의 컨텍스트에서 수행됩니다.
세션을 사용할 때는 다음과 같은 제한 사항이 적용 .
스레드 간에 세션을 주식 할 수 없습니다. 세션은 스레드로부터 안전하지 않습니다.
세션을 중첩할 수 없습니다. 예시 들어, 다른 모델 클래스의
with_session
메서드에 전달된 차단 내의 모델 클래스에서with_session
메서드를 호출할 수 없습니다. 다음 코드는 오류를 발생시키는 중첩된 세션을 보여줍니다.Book.with_session(causal_consistency: true) do # Nesting sessions results in errors Film.with_session(causal_consistency: true) do ... end end 세션 차단 내에서 사용되는 모든 모델 클래스와 인스턴스는 동일한 운전자 클라이언트 사용해야 합니다. 예시 들어, 차단 에 사용된 모델에 대해
with_session
을(를) 호출한 모델 또는 인스턴스 와 다른 클라이언트 지정하는 경우 Mongoid는 오류를 반환합니다.
예시
모델 클래스에서 with_session
메서드를 사용하고 세션 옵션을 전달하여 세션의 컨텍스트에서 작업 차단 수행할 수 있습니다.
다음 코드는 causal_consistency
모델에서 세션을 생성할 때 작업 순서를 보장하도록 옵션을 활성화한 Book
다음 데이터 작업을 수행합니다.
Book.with_session(causal_consistency: true) do Book.create! book = Person.first book.title = "Swann's Way" book.save end
사용 가능한 세션 옵션에 대해 자세히 학습 Ruby 운전자 API 문서에서 세션 클래스 생성자 세부 정보를 참조하세요.
또는 모델의 인스턴스 에서 with_session
메서드를 사용하고 여기에 세션 옵션을 전달하여 세션의 컨텍스트에서 작업 차단 수행할 수 있습니다.
다음 코드는 causal_consistency
옵션을 활성화하여 Book
인스턴스 에 세션을 생성할 때 작업 순서를 보장한 다음 데이터 작업을 수행합니다.
book = Book.new book.with_session(causal_consistency: true) do book.title = 'Catch-22' book.save book.sellers << Shop.create! end
추가 정보
트랜잭션에 대해 자세히 학습 서버 매뉴얼의 트랜잭션을 참조하세요.
CRUD 작업 수행에 대해 자세히 학습 데이터 작업 수행 가이드 참조하세요.