Typeorm 트랜잭션

jimin·2022년 8월 8일
0

nodeJs

목록 보기
5/5

트랜잭션은 무엇인가?

트랜잭션(Transaction) 이란 데이터베이스의 상태를 변화시키기 위해 SELECT, UPDATE, INSERT, DELETE와 같은 연산을 수행하는 작업의 논리적 단위다.

요청을 처리하는 과정에서 데이터베이스에 변경이 일어나는 요청을 독립적으로 분리하고 에러가 발생했을 경우 이전 상태로 되돌리게 하기 위해 데이터베이스에서 제공하는 기능입니다.

트랜잭션의 특징(ACID)

원자성(Atomicity)

원자성은 트랜잭션이 DB에 모두 반영되거나, 전혀 반영되지 않는 All or Nothing 방식을 의미한다.

일관성(Consistency)

일관성은 트랜잭션 작업 처리의 결과가 항상 일관되어야 한다를 뜻한다.

독립성(Isolation)

독립성은 하나의 트랜잭션은 다른 트랜잭션에 끼어들 수 없고 마찬가지로 독립적임을 의미한다.
즉, 각각의 트랜잭션은 독립적이라 서로 간섭이 불가능하다.

지속성(Durability)

지속성은 트랜잭션이 성공적으로 완료되면 영구적으로 결과에 반영되어야 함을 뜻한다.
보통 commit 이 된다면 지속성은 만족할 수 있다.

트랜잭션의 Commit 과 Rollback

Commit

하나의 트랜잭션이 성공적으로 끝나면 이 변경사항을 한꺼번에 DB에 반영한다.

Rollback

트랜잭션의 원자성이 깨질 때, 즉 하나의 트랜잭션 처리가 비정상적으로 종료 되었을 때 트랜잭션 실행 전으로 되돌린다.

트랜잭션 with Typeorm

TypeORM에서 트랜잭션을 사용하는 방법은 3가지가 있습니다.

  • QueryRunner를 이용해서 단일 DB 커넥션 상태를 생성하고 관리하기
  • transaction 객체를 생성해서 이용하기
  • @Transaction, @TransactionManager, @TransactionRepository 데코레이터를 사용하기

QueryRunner 클래스를 사용하는 방법

QueryRunner를 이용하면 트랜잭션을 완전히 제어할 수 있습니다.

        // transaction 처리

		//주입받은 Connection 객체에서 QueryRunner를 생성
        const queryRunner = this.dataSource.createQueryRunner();
		// QueryRunner에서 DB에 연결 후 트랜잭션을 시작
        await queryRunner.connect();
        await queryRunner.startTransaction();

        try{
            // 작업 수행 (사용자 삭제)
            await this.deleteUser(user);
         
            //정상 동작을 수행했다면 트랜잭션을 커밋하여 영속화
            await queryRunner.commitTransaction();

        } catch (err) {
            // 에러가 생기면 rollback
            await queryRunner.rollbackTransaction();
        } finally {
            // 직접 생성한 QueryRunner는 해제시켜 주어야 함
            await queryRunner.release();
        }

transaction 객체를 생성해서 이용하는 방법

connection 객체내의 transaction 메서드를 바로 이용하는 방법이다.

transaction<T>(runInTransaction: (entityManager: EntityManager) => Promise<T>): Promise<T>;
// 주어진 함수 실행을 트랜잭션으로 래핑합니다.
await this.connection.transaction(async manager => {
    await this.deleteUser(user);
 })

@Transaction, @TransactionManager, @TransactionRepository 데코레이터를 사용하는 방법

Nest에서는 권장하지는 않는 방법이다.

@Transaction()
delete(user: User, @TransactionRepository(User) userRepository: Repository<User>) {
    return userRepository.save(user);    
}
profile
안녕하세요 백엔드 개발자 지민입니다.

0개의 댓글