본문 바로가기
개발 프레임워크/NestJS

[MongoDB, NestJS] DB 트랜잭션을 이용한 자원소비 코드

by minhyeok.lee 2023. 3. 26.
반응형

[NestJS, MongoDB] DB 자원(임계구역)에 동시접근할 때, 트랜잭션을 이용해 자원소비 제어 코드

Why?

 1. DB자원이 0이하로 내려가지 않게 백엔드에서 구현한다. (자원이 0이하면 소비할 수 없고 Error처리)

 2. 하지만 트랜잭션을 걸어주지 않는다면 DB 임계구역에 있는 자원에 동시에 접근하여 소비하여 자원이 동시에 -2가 되어 자원이 -1이 되는 경우가 있다.

 

이를 해결하기 위해 트랜잭션을 걸어주는 코드이다. (동시에 접근하는 것을 방지한다)

async spendResource() {
    const session = await this.model.db.startSession();
    session.startTransaction();
    try{

        // 자원이 없으면 예외처리 추가 부분 (rollback)
        if(!resource) throw BadRequestException();
        ...

        await session.commitTransaction();

    } catch (error) {

        await session.abortTransaction();

        throw error;


    } finally {

        session.endSession();

    }
}

1. try 구문에서 자원이 없으면 예외처리를 해주고 자원이 있으면 commit(저장)하고 완료한다.

2. catch 구문에서 문제가 생기면 error을 발생하고 트랜잭션을 abort(중단)한다.

3. finally 구문에서 session을 종료한다.

 

위 로직은 하나의 프로세스씩 실행된다.

Transaction은 복수개의 작업들을 격리된(isolation) 상태로 진행하게 해준다.

복수개의 작업이 모두 성공했을 때만 성공하게 되고 이를 commit 한다.

하나라도 실패하게 되면 모두가 실패하게 되고 이를 abort 한다.

실패하게 된다면 transaction 작업 전의 상태로 되돌아가게 된고 이를 rollback이라 한다.

 


 

* 참고
MongoDB에서 transaction은 replicaset에서만 가능하다.

standalone에서는 불가능하다.
mongoose 버전이 5.2.0 이상이어야한다.
Transaction은 MongoDB sessions에 구성되어 있다.

startSession()를 호출한뒤 startTransaction()을 호출하여야 트렌젝션을 시작할 수 있다.

트렌젝션 안에서 작업을 실행하려면 session을 옵션으로 전달해야한다.

반응형

댓글