MongoDB의 쓰기( UPDATE와 DELETE ) 오퍼레이션은 도큐먼트 단위의 원자성( Atomicity )만 제공한다.

하나의 쓰기 오퍼레이션으로 여러 도큐먼트를 변경하거나 삭제하더라도, MongoDB 서버는 내부적으로 하나의 트랜잭션으로 하나의 도큐먼트만 처리하는 방식으로 작동한다.

 

그래서 MongoDB 서버에서 일반적으로 쓰기 오퍼레이션으로 여러 도큐먼트를 변경하면, 오퍼레이션이 완료되기도 전에 먼저 변경된 데이터들은 다른 컨넥션에서 즉시 조회를 할 수 있게 된다.

 

 

만약 하나의 UPDATE나 DELETE 명령이 완료되기 전까지는 다른 커넥션에서 변경 내용을 확인하지 못하게 하려면, 격리된 UPDATE 또는 DELETE 또는 REMOVE 명령을 사용해야 한다.

 

다음 예제는 UPDATE와 REMOVE 명령을 사용하는 방법을 보여주고 있다.

UPDATE 명령과 REMOVE 명령 모두 업데이트 대상 도큐먼트를 검색하는 조건과 함께 "$isolated : 1" 옵션을 사용하면 된다.

mongo> db.users.remove( { score : { $lt : 50 }, $isolated : 1 } );

mongo> db.users.update(
      { score : { $gt : 90 }, $isolated : 1 }
    , { $set : { grade : "A" } }
    , { multi : true }
);

 

MongoDB 서버는 UPDATE나 REMOVE 명령에 $isolated 옵션을 사용하면, 데이터 변경 작업이 완료될 때까지 다른 컨넥션이 변경 중인 데이터를 조회할 수 없다.

 

즉 UPDATE나 REMOVE 명령이 10건의 도큐먼트를 변경해야 하는데, 작업 도중 에러가 발생하면 MongoDB 서버가 이미 처리된 도큐먼트에 대해서 롤백을 수행하거나 하지는 않는다.

 

$isolated 옵션은 정상적으로 처리될 때에만 필요한 격리 수준을 보장해 준다.

 

※ 주의

MongoDB의 $isolated 옵션은 꼭 필요한 경우에만 제한적으로 사용할 것을 권장한다. MongoDB 서버는 $isolated 옵션을 사용한 업데이트 명령의 격리 수준을 보장하기 위해서 업데이트 대상 컬렉션에 대해서 쓰기 잠금( Exclusive Lock )을 걸고 처리를 한다. 이는 MongoDB 엔진이 컬렉션 레벨의 잠금을 걸기 때문에 MMAPv1 스토리지 엔진뿐만 아니라 도큐먼트 레벨의 잠금을 지원하는 WiredTiger 스토리지 엔진에서도 동일하게 작동한다. 즉 $isolated 옵션을 설정한 UPDATE나 REMOVE 명령이 수행되는 동안에는 다른 컨넥션에서 어떤 쿼리나 데이터 변경 명령을 실행하지 못한다. 만약 읽고 쓰기가 빈번하게 실행되는 컬렉션에 대해서 $isolated 옵션을 설정한 UPDATE나 DELETE 명령이 실행되면 다른 컨넥션의 수많은 쿼리나 업데이트 명령들이 일시적으로 처리를 멈추게 되고, 응용 프로그램은 데이터베이스의 응답을 받지 못해서 더 많은 쓰레드나 컨넥션을 생성하면서 처리 불가 상태로 빠지게 될 가능성이 높다.

 

참고 : https://secretartbook.tistory.com/6


to Top