2012-05-09 5 views
4

스키마 :MongoDB를 업데이트 여러 문서

{ 
    name: "b", 
    available: true, 
    for: ["a", "b] 
} 

내가 거짓 = a.available 업데이트 할 경우 :

{ 
    name: "a", 
    available: true, 
    for: ["b", "c"] 
} 

와 "B"

{ 
    name: String, 
    available: Boolean, 
    for: String 
} 

"A"가 나는 b.available = false를 동시에 업데이트해야한다. 두 문서를 업데이트하고 "a"와 "b"를 업데이트 할 때 "b"가되는 다른 프로세스/스레드가 없는지 확인하는 방법은 무엇입니까?

답변

5

MongoDB는 원 자성 트랜잭션을 지원하지 않습니다. 따라서 두 번째 업데이트가 실패한 경우 첫 번째 업데이트를 "실행 취소"해야하는 경우 운이 없어진 것입니다.

그러나 제한된 경우 MongoDB는 격리 된 업데이트를 지원합니다. 이 업데이트는 전부 또는 일부가 아니지만 MongoDB는 아무도 당신의 글을 쓰는 동안 콜렉션에 쓰지 않는다고 보장합니다.

주요주의의 몇 :

  • 문서는 모든
  • 업데이트는 모든 예를 들어 당신을 바탕으로 하나 개의 쿼리

지정해야합니다 같은 콜렉션에 있어야합니다 제공 했으므로 사례가 자격을 얻을 수 있습니다.

Here은 격리 된 업데이트를 설명하는 설명서입니다. 기본적으로

당신이 이름 중 하나 "a"또는 "b"때 false로 원자 적으로 설정 "가능"에 다음과 유사한 업데이 트를 발행 할 수 있습니다 :

db.blah.update({"name": {"$in": ["a", "b"]}, "$atomic": 1}, {"available": false}); 
+0

다른 문서를 원자 적으로 다른 값으로 업데이트하려면 어떻게해야합니까? name == "a"일 경우 update count = 1; name == "b"일 경우 update count = 2입니다. – Kevin

+0

그건 아마도 불가능합니다. 앞서 말했듯이,이 기능에는 몇 가지 중요한 제한이 있습니다. MongoDB는 그런 종류의 일을 위해 실제로 설계되지 않았습니다. –

3

당신이 정말 필요한 경우 ,이 논리를 mongodb 위에 구현하는 것이 가능할 수도 있습니다 (응용 프로그램에서 또는 mongo 드라이버의 래퍼에서 더 좋음).

격리 속성을 요청하는 중입니다. 이를 달성하는 한 가지 방법은 MVCC 패턴을 사용하는 것입니다. 이것은 실제로 잔인한 일이지만 이것은 mongodb와 ACID 속성이 모두 필요한 경우 수행 할 수있는 작업에 대한 아이디어를 제공하기위한 것입니다.

MVCC 패턴의 일반적인 구현은 here으로 설명됩니다. 이 구현을위한 github에도 project이 있지만 Java 프로젝트입니다.

SO question 및 그 대답을 볼 수도 있습니다. 나의 현재 대답은 그것의 요약이다.