2014-03-25 2 views
0

IMongoDB를

 coll_name = "#{some_name}_#{differentiator}" 
     coll_object = @database[coll_name] 
     idExist = coll_object.find({"adSet.name" => NAME}).first() 
     if idExist.nil? 
      docId = coll_object.insert(request) 
     else 
      docId = idExist["_id"] 
     end 
     return docId 

미분 코드가 있음 루프에서 동일하거나 상이 할 수있는 코드의 다음 부분이 called.So 매번이있을 수있다 가지고 새로운 콜렉션 또는 동일한 콜렉션. 동일한 콜렉션이 수신되면 name = NAME 인 오브젝트가있을 수 있습니다. 그 경우 삽입이 수행되어야합니다. 그러나 동일한 이름을 가진 문서가 삽입되는 것을 관찰했습니다. 아무도이 문제에 대해 도움이 될 수 없습니다.

답변

0

이 동작에 대한 설명은 경쟁 조건 일 수 있습니다. 응용 프로그램의 3 번째 줄과 5 번째 줄 사이에 다른 스레드/프로세스에 의해 복제본이 삽입됩니다. 두 개의 스레드가 동시에 같은 이름을 만들려고 시도하면 데이터베이스는 이름이 아직 존재하지 않음을 반환하고, 그 응답이 도착하면 두 문서 모두를 삽입합니다.

이 문제가 발생하지 않도록하려면 이름 필드에 create an unique index을 입력하십시오. 이것은 MongoDB가 같은 이름의 두 개의 문서를 삽입하는 것을 막을 것입니다. 이렇게하면 삽입하기 전에 존재 확인을 제거 할 수 있습니다. 문서를 삽입 한 다음 getLastError를 호출하여 제대로 작동하는지 확인하십시오. 그렇지 않은 경우 추가 쿼리를 사용하여 기존 문서를 검색하십시오.

+0

이것은 하나의 프로세스이며 스레드가 포함되어 있지 않습니다. 왜 이런 일이 일어날 수 있는지 다른 이유가있을 수 있습니다. – nnm

+0

@nnm ​​안전하지 않은 쓰기 문제를 사용하고 문서를 빠르게 연속해서 삽입하는 경우 나중에 잠깐 검색 할 때 삽입이 아직 처리되지 않았을 수 있습니다. 그러나 실제로 특정 값에 대해 고유성을 적용하려는 경우 고유 인덱스를 사용하십시오. – Philipp

+0

coll_object.create_index ([[ "adSet.name", Mongo :: GEO2D]])와 coll_object.ensure_index ([[ "adSet.name", Mongo :: GEO2D])를 추가하고 의도적으로 같은 이름입니다. 어떤 예외도 발생시키지 않고 모든 복제물을 저장합니다. 5 초의 수면을 추가하여 처음으로 넘어지기 전에 두 번째 삽입을 피했습니다.하지만 여전히 중복이 유지됩니다. 왜요? – nnm