웅글웅글: Nest 게시판 + 채팅 6. Transaction😱

메밀·2024년 3월 14일
0

웅글웅글: NestJS

목록 보기
6/9
post-thumbnail

1. 다시 돌아온 Transaction

다 되거나 안 되게 하는 그것.
Spring Boot에서 @Transaction 띡 붙여서 해결하던 그거에 대해서 알아보려고 한다.

2. NestJS의 트랜잭션

1) Spring 압승 🎉

트랜잭션 구현은 Spring Boot의 압도적인 승리다.
대충 아래와 같은 Spring Boot 코드와 똑같이 동작하는 코드를 NestJS에서 작성하려면 얼마나 귀찮아지는지 알아보자.

@Transactional
public void transactionTest() {
	entityARepository.save(entityA);
	entityBRepository.save(entityB);
}

2) QueryRunner를 사용한 Transaction😨

@Injectable()
export class TransactionTestService {
  constructor(
    private dataSource: DataSource // ⭐️ 1
  ) {  }

  // 트랜잭션 테스트
  async saveBoard(): void {
    const queryRunner = this.dataSource.createQueryRunner();

    await queryRunner.connect();
    await queryRunner.startTransaction();

    try {
      // 로직
      const savedEntityA = await queryRunner.manager.save(entityA);
      const savedEntityB = await queryRunner.manager.save(entityB);
      
      await queryRunner.commitTransaction();
    } catch (error) {
      await queryRunner.rollbackTransaction();
    } finally {
      await queryRunner.release();
    }
  }
}

DataSource 객체를 주입하고, try-catch-finally 블록을 통해 성공 시 커밋 / 실패 시 롤백, queryRunner 리소스 해제를 해줘야 한다.

Model1으로 만들었던 쇼핑몰의 악몽이 떠오른다...😱

3) 쇼핑몰의 악몽과 try-catch 지옥😱

개발 공부 초기에 Model1 방식으로 쇼핑몰을 만들었던 적이 있다.
그때 정확히 트랜잭션을 저렇게 처리했었다.

	public boolean addEmployee(Employee paramEmployee) {
		boolean result = true; // 메소드 실행 결과값을 담을 변수
		Connection conn = null;
		
		try {
			this.dbUtil = new DBUtil();
			conn = dbUtil.getConnection();
			conn.setAutoCommit(false);
			
			this.employeeDao = new EmployeeDao();
			
			if(employeeDao.insertEmployee(conn, paramEmployee) != 1) {
				// 오류는 나지 않았지만 정상적 삽입도 아닌 경우 의도적으로 오류를 발생시킴
				throw new Exception(); 
			}
			
			conn.commit();
			System.out.println("addEmployee() 성공");
			
		} catch(Exception e) {
			result = false;
			
			e.printStackTrace();
			
			try {
				conn.rollback();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
			
		} finally {
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		
		return result;
	}

사실 처음 이 코드를 배울 땐 Transaction이라는 개념 자체가 너무 신기해서 귀찮은지 몰랐다.

하지만 그것마저도 메소드 몇 개 만들고 나니 황당할정도로 귀찮아 졌고, try 블록 안의 코드만 바꿔끼울 수 있는 방법이 없는지 궁금했던 기억이 난다.

끝내 이 방법으로 쇼핑몰을 완성하고 Spring Boot를 처음 배웠을 때 얼마나 혁신ㅋㅋㅋ적이었는지도!

3. 요약과 남은 의문

QueryRunner를 사용한 트랜잭션은 NestJS 공식문서를 통해 학습한 것이다. 뭔가 더 편한 방법이 있을수도 있다. 인터셉터를 직접 구현하거나?

어쨌거나 공식문서 기준 NestJS의 트랜잭션은 당황스러운걸로...

0개의 댓글