Computer >> 컴퓨터 >  >> 프로그래밍 >> MongoDB

MongoDB 트랜잭션 잠금 구현하기 – findOneAndUpdate() 활용 가이드

MongoDB 4.0 환경에서는 완전한 멀티 도큐먼트 트랜잭션 기능이 제공되지 않습니다. 대신 findOneAndUpdate() 메서드를 활용하면 원자적(atomic) 연산을 통해 트랜잭션과 유사한 결과를 얻을 수 있습니다. 이 방식은 문서를 조회하면서 동시에 업데이트하는 단일 원자적 작업으로, 여러 클라이언트가 동시에 같은 문서에 접근하는 상황에서도 경쟁 조건(race condition)을 방지할 수 있습니다.

1단계: 샘플 컬렉션 생성

먼저 문서가 담긴 컬렉션을 생성합니다.

> db.demo404.insertOne({"FirstName":"John"});
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5e6f8c38fac4d418a0178592")
}
> db.demo404.insertOne({"FirstName":"Robert"});
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5e6f8c3cfac4d418a0178593")
}
> db.demo404.insertOne({"FirstName":"Mike"});
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5e6f8c40fac4d418a0178594")
}

2단계: find()로 전체 문서 조회

find() 메서드를 사용하면 컬렉션의 모든 문서를 한눈에 확인할 수 있습니다.

> db.demo404.find();

위 명령을 실행하면 다음과 같은 출력이 반환됩니다.

{ "_id" : ObjectId("5e6f8c38fac4d418a0178592"), "FirstName" : "John" }
{ "_id" : ObjectId("5e6f8c3cfac4d418a0178593"), "FirstName" : "Robert" }
{ "_id" : ObjectId("5e6f8c40fac4d418a0178594"), "FirstName" : "Mike" }

3단계: findOneAndUpdate()로 잠금 설정

다음은 findOneAndUpdate()를 사용해 MongoDB에서 잠금(lock)을 설정하는 쿼리입니다. in_transaction 필드가 아직 존재하지 않는 첫 번째 문서를 찾아 해당 필드를 true로 설정함으로써, 다른 프로세스가 동일한 문서를 중복 처리하지 못하도록 막습니다.

> result=db.demo404.findOneAndUpdate({"in_transaction": {"$exists": false}}, {"$set": {"in_transaction": true}});

실행 결과는 다음과 같습니다.

{ "_id" : ObjectId("5e6f8c38fac4d418a0178592"), "FirstName" : "John" }

출력에서 확인할 수 있듯이, in_transaction 필드가 없던 첫 번째 문서(John)가 선택되어 잠금 처리되었습니다. 이후 다른 요청이 같은 조건으로 접근하면 해당 문서에는 이미 필드가 존재하기 때문에 자동으로 제외됩니다. 이처럼 findOneAndUpdate()의 원자성을 활용하면 간단한 분산 잠금(distributed lock) 패턴을 손쉽게 구현할 수 있습니다.