영호

[TypeORM] @Transaction 적용 본문

TypeORM

[TypeORM] @Transaction 적용

0h0 2022. 5. 20. 13:54
반응형

들어가며

이번 글에서는 @Transaction 데코레이터를 이용하여 TypeORM에서 트랜잭션을 적용하는 방법에 대해 알아보겠습니다.

TypeORM에서 트랜잭션을 적용하는 방법으로는 3가지 정도가 있습니다.

1. QueryRunner 2. getConnection 3. @Transaction데코레이터

저는 그중 간단하게 사용 가는 한 3번째 방법인 @Transaction데코레이터를 이용하겠습니다.

트랜잭션에 대한 개념을 모르시는 분들은 이 글을 참고해주시면 감사하겠습니다.

@Transaction 사용방법

우선 @TransactionManager가 필요하기 때문에 parameter에 해당 내용을 추가해줍니다. 이후 저희가 원하는 DB 관련 로직을 작성해주면 됩니다.

저는 퇴근 일지를 의미하는 WorkDiary와 해당 퇴근 일지와 관련 있는 이미지들을 저장하는 WorkDiaryImg 엔티티에 저장하는 행위를 하나의 트랜잭션으로 설정하고 퇴근일지가 저장된 후 관련 이미지를 저장하는데 에러가 발생하면 모든 걸 rollback 하길 원하기 때문에 아래 코드와 같이 로직을 작성했습니다.

@Transaction()
    static async saveWorkDiary(mappingId : number ,imgList : string[], issue: string, mappingInfo: Mapping,
        @TransactionManager() manager? : EntityManager
        ){
            const diary: WorkDiary = new WorkDiary();
            diary.issue = issue;
            diary.mapping = mappingInfo
            const writeDiaryRes = await manager.save(WorkDiary, diary);
            // throw "error"
            for(let i = 0; i < imgList.length;i++){
                const workdiaryImg:WorkDiaryImg = new WorkDiaryImg();
                workdiaryImg.image = imgList[i];
                workdiaryImg.workDiary = writeDiaryRes;
                workdiaryImg.save();
            }

    }

실행결과

위와 같이 @Transaction을 설정 후 코드를 실행시켜 보면 정상적인 상황에서는 잘 동작되는 것을 볼 수 있습니다. 그러나 아래 코드처럼 이미지를 저장하는 for문 전에 일부러 에러를 발생시킨다면 @Transaction데코레이터로 인해 모든 것은 rollback 됩니다.

@Transaction()
    static async saveWorkDiary(mappingId : number ,imgList : string[], issue: string, mappingInfo: Mapping,
        @TransactionManager() manager? : EntityManager
        ){
            const diary: WorkDiary = new WorkDiary();
            diary.issue = issue;
            diary.mapping = mappingInfo
            const writeDiaryRes = await manager.save(WorkDiary, diary);
            
            throw "error"
            
            for(let i = 0; i < imgList.length;i++){
                const workdiaryImg:WorkDiaryImg = new WorkDiaryImg();
                workdiaryImg.image = imgList[i];
                workdiaryImg.workDiary = writeDiaryRes;
                workdiaryImg.save();
            }

    }
  • 또한 아래 코드와 같이 격리 레벨도 같이 설정 가능합니다
@Transaction({ isolation: "SERIALIZABLE" })
반응형

'TypeORM' 카테고리의 다른 글

[TypeORM] Active-record 패턴  (0) 2022.05.19
[TypeORM] TypeORM entity 작성  (0) 2022.05.14
[TypeORM] 공식문서로 TypeORM + MySQL설정하기  (0) 2022.05.09
Comments