트랜잭션
MongoDB 서버 버전 4.0 에는 다중 문서 트랜잭션이 도입되었습니다. (단일 문서 내의 여러 필드에 대한 업데이트는 모든 버전의 MongoDB 에서 원자적으로 이루어집니다). 트랜잭션에는 비독립형 MongoDB 토폴로지 와 Ruby 운전자 버전 2.6 이상이 필요합니다. 상위 수준의 트랜잭션 API 에는 Mongoid 버전 9.0 이상이 필요하고 하위 수준 API 에는 Mongoid 버전 6 이(가) 필요합니다.4 이상입니다.
트랜잭션 사용
상위 레벨 API
트랜잭션 은 Mongoid 문서 클래스의 인스턴스 , Mongoid 문서 클래스 또는 Mongoid
모듈에서 transaction
메서드를 호출하여 시작할 수 있습니다.
Band.transaction do Band.create(title: 'Led Zeppelin') end band = Band.create(title: 'Deep Purple') band.transaction do band.active = false band.save! end Mongoid.transaction do band.destroy end
transaction
메서드가 호출되면 Mongoid가 다음을 수행합니다.
클라이언트 에서
transaction
메서드 호출의 수신자가 사용하는 세션을 만듭니다.세션에서 트랜잭션 을 시작합니다.
주어진 차단 을 실행합니다.
차단 에서 예외가 발생하지 않으면 트랜잭션 을 커밋합니다.
트랜잭션 내부에서 수정된 모든 객체에 대해
after_commit
콜백을 호출합니다.
차단 에서 예외가 발생하면 트랜잭션 을 중단합니다.
트랜잭션 내부에서 수정된 모든 객체에 대해
after_rollback
콜백을 호출합니다.
세션을 닫습니다.
참고
트랜잭션은 특정 클라이언트에 연결되므로 동일한 클라이언트에서의 작업만 트랜잭션 범위가 됩니다. 따라서 동일한 클라이언트를 사용하는 객체만 transaction
메서드 블록 내에서 사용하는 것이 좋습니다.
class Author include Mongoid::Document store_in client: :encrypted_client end class User include Mongoid::Document store_in client: :encrypted_client end class Article include Mongoid::Document # This class uses the :default client end # Transaction is started on the :encrypted_client Author.transaction do # This operation uses the same client, so it is in the transaction Author.create! # This operation also uses the same client, so it is in the transaction User.create! # This operation uses a different client, so it is NOT in the transaction Article.create! end
참고
Mongoid
모듈에서 transaction
메서드가 호출되면 :default
클라이언트를 사용하여 트랜잭션이 생성됩니다.
트랜잭션 중단
transaction
메서드 블록 내에서 예외가 발생하면 트랜잭션이 중단됩니다. 일반적으로 발생한 예외는 Mongoid::Errors::Rollback
을(를) 제외하고 전달됩니다. 예외를 전달하지 않고 트랜잭션을 명시적으로 중단하려는 경우 이 오류가 발생해야 합니다.
콜백
트랜잭션 API 에는 after_commit
및 after_rollback
라는 두 가지 새로운 콜백이 도입되었습니다.
after_commit
생성, 저장 또는 폐기된 객체 에 대해 콜백 이 트리거됩니다.
객체 가 트랜잭션 내부에서 수정된 경우 트랜잭션 이 커밋된 후 ;
객체가 트랜잭션 외부에서 수정된 경우 객체가 지속된 후
참고
어떤 경우든 after_commit
콜백 은 다른 모든 콜백이 성공적으로 실행된 후에만 트리거됩니다. 따라서 트랜잭션 없이 객체 를 수정하는 경우 객체 가 유지되었지만 after_commit
콜백 이 트리거되지 않았을 수 있습니다( 예시: after_save
콜백 에서 예외가 발생함).
after_rollback
트랜잭션 이 중단된 경우 트랜잭션 내에서 생성, 저장 또는 파기된 객체 에 대해 콜백 이 트리거됩니다. 트랜잭션 없이는 after_rollback
이(가) 트리거되지 않습니다.
하위 수준 API
트랜잭션 을 시작하려면 애플리케이션 에 세션이 있어야 합니다.
트랜잭션 은 세션에서 start_transaction
메서드를 호출하여 시작할 수 있으며, 모델 클래스 또는 인스턴스 에서 with_session
메서드를 호출하여 가져올 수 있습니다.
class Person include Mongoid::Document end Person.with_session do |session| session.start_transaction end person = Person.new person.with_session do |session| session.start_transaction end
트랜잭션을 시작할 때 읽기 고려 (read concern), 쓰기 고려 (write concern), 읽기 설정 (read preference)을 지정할 수도 있습니다.
Person.with_session do |session| session.start_transaction( read_concern: {level: :majority}, write_concern: {w: 3}, read: {mode: :primary}) end
트랜잭션 은 커밋되거나 중단될 수 있습니다. 이를 수행하는 해당 메서드는 세션 인스턴스 에서 commit_transaction
및 abort_transaction
입니다.
Person.with_session do |session| session.commit_transaction end Person.with_session do |session| session.abort_transaction end
세션이 열린 트랜잭션으로 종료 되면 트랜잭션이 중단 됩니다.
트랜잭션 커밋이 실패하면 다시 시도할 수 있습니다 . 이를 위한 Ruby 코드는 다음과 같습니다.
begin session.commit_transaction rescue Mongo::Error => e if e.label?(Mongo::Error::UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL) retry else raise end end
트랜잭션 내에서 작업을 수행하려면 작업에서 세션이 시작된 것과 동일한 클라이언트를 사용해야 합니다. 기본적으로 모든 작업은 기본 클라이언트에서 수행됩니다.
class Person include Mongoid::Document end class Post include Mongoid::Document end Person.with_session do |s| s.start_transaction Person.create! Person.create! Post.create! s.commit_transaction end
다른 클라이언트 를 명시적으로 사용하려면 with
메서드를 사용합니다.
Post.with(client: :other) do Person.with(client: :other) do Person.with_session do |s| s.start_transaction Person.create! Person.create! Post.create! s.commit_transaction end end end