MongoDB 에서 쓰기 (write) 작업은 여러 값을 수정하는 경우에도 단일 문서 수준에서 원자적으로 이루어집니다. 병렬 업데이트의 경우 각 명령은 쿼리 조건이 여전히 일치하는지 확인합니다.
동시 업데이트 중 충돌을 방지하려면 업데이트 필터하다 에 예상 현재 값을 포함합니다.
사용 사례
이 문서 포함된 컬렉션 생각해 보세요.
db.games.insertOne( { _id: 1, score: 80 } )
이러한 업데이트 작업은 동시에 발생합니다.
// Update A db.games.updateOne( { score: 80 }, { $set: { score: 90 } } ) // Update B db.games.updateOne( { score: 80 }, { $set: { score: 100 } } )
한 번의 업데이트 score 을 90 또는 100로 설정합니다. 그러면 두 번째 업데이트 { score: 80 } 일치에 실패하고 실행 되지 않습니다.
경고
업데이트 하지 않는 필드 필터링하면 동시 업데이트 중에 예기치 않은 결과가 발생할 수 있습니다. 다음 작업을 고려하세요.
// Update A db.games.updateOne( { _id: 1 }, { $set: { score: 90 } } ) // Update B db.games.updateOne( { _id: 1 }, { $set: { score: 100 } } )
두 업데이트 모두 { _id: 1 }와 일치하므로 둘 다 실행. 두 번째 업데이트 첫 번째 업데이트를 덮어씁니다. 첫 번째 클라이언트 업데이트 손실되었다는 경고를 받지 못합니다.
업데이트되지 않은 필드를 필터링할 때 충돌을 방지하려면 를 $inc 사용합니다.
예시 를 들어 다음과 같은 동시 업데이트 작업을 가정해 보겠습니다.
// Update A db.games.updateOne( { _id: 1 }, { $inc: { score: 10 } } ) // Update B db.games.updateOne( { _id: 1 }, { $inc: { score: 20 } } )
두 업데이트 모두 { _id: 1 }와 일치합니다. 값을 설정하다 것이 아니라 증가시키기 때문에 서로 덮어쓰지 않습니다. 마지막 score 는 110입니다.
세부 정보
이 섹션에서는 다중 문서 트랜잭션에 대한 추가 세부 정보를 설명합니다.
단일 쓰기 작업(예: db.collection.updateMany())이 여러 문서를 수정하는 경우 각 문서의 수정은 원자적이지만 전체 작업은 원자적이지 않습니다.
단일 쓰기 작업이든 다중 쓰기 작업이든 다중 문서 쓰기 작업을 수행할 때 다른 작업과 겹칠 수 있습니다.
여러 문서(단일 또는 여러 컬렉션)에 대한 읽기 및 쓰기의 원자성이 필요한 상황의 경우, 복제본 세트 및 샤딩된 클러스터에서의 트랜잭션을 포함한 분산 트랜잭션을 지원합니다.
자세한 내용은 트랜잭션을 참조하세요.
중요
대부분의 경우 분산 트랜잭션은 단일 문서 쓰기에 비해 더 큰 성능 비용이 발생하므로 분산 트랜잭션의 가용성이 효과적인 스키마 설계를 대체할 수는 없습니다. 대부분의 시나리오에서 비정규화된 데이터 모델 (내장된 문서 및 배열) 은 계속해서 데이터 및 사용 사례에 최적일 것입니다. 즉, 대부분의 시나리오에서 데이터를 적절하게 모델링하면 분산 트랜잭션의 필요성이 최소화됩니다.
추가 트랜잭션 사용 고려 사항(예: 런타임 제한 및 oplog 크기 제한)은 프로덕션 고려사항을 참조하세요.