본문 바로가기
프로그래밍/TypeORM

[TypeORM] Transactions

by YuminK 2023. 8. 31.

https://orkhan.gitbook.io/typeorm/docs/transactions

 

Creating and using transactions

트랜잭션은 DataSource 또는 EntityManager를 사용하여 생성된다.

 

예시

await myDataSource.transaction(async (transactionalEntityManager) => {
    // execute queries using transactionalEntityManager
})

 

await myDataSource.manager.transaction(async (transactionalEntityManager) => {
    // execute queries using transactionalEntityManager
})

 

트랜잭션에서 처리하고 싶은 모든 것은 callback 내부에서 실행되어야 한다.

 

await myDataSource.manager.transaction(async (transactionalEntityManager) => {
    await transactionalEntityManager.save(users)
    await transactionalEntityManager.save(photos)
    // ...
})

 

트랜잭션 사용에 가장 중요한 제약사항은 '항상' 제공된 entityManager 인스턴스를 사용하는 것이다.

전역 EntityManger를 사용하지 마라. 모든 연산은 제공된 transactional entity manager로 처리 되어야만 한다.

 

Specifying Isolation Levels

첫번째 인자로 고립 수준을 설정할 수 있다. 

 

await myDataSource.manager.transaction(
    "SERIALIZABLE",
    (transactionalEntityManager) => {},
)

 

고립 수준은 모든 데이터베이스에서 독립적으로 처리되지 않는다.

 

다음 db 드라이버는 표준 고립 수준을 지원한다.

(READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ, SERIALIZABLE)

 

1. MySql

2. Postgres

3. SQL Server

 

SQLite는 SERIALIZABLE로 트랜잭션을 처리하지만,

공유된 캐시모드를 활성화하는 경우 트랜잭션은 READ UNCOMMITTED를 사용할 수 있다.

 

Oracle의 경우, 오직 READ COMMITTED와 SERIALIZABLE를 지원한다.

 

Using QueryRunner to create and control state of single database connection

QueryRunner는 싱글 데이터베이스 연결을 제공한다.

트랜잭션은 쿼리러너를 사용하도록 조직화되어 있다. 싱글 트랜잭션은 싱글 쿼리 러너에서 사용될 수 있다.

쿼리러너 객체를 하나 만들고, 수동으로 트랜잭션 상태를 제어할 수 있다.

// create a new query runner
const queryRunner = dataSource.createQueryRunner()

// establish real database connection using our new query runner
await queryRunner.connect()

// now we can execute any queries on a query runner, for example:
await queryRunner.query("SELECT * FROM users")

// we can also access entity manager that works with connection created by a query runner:
const users = await queryRunner.manager.find(User)

// lets now open a new transaction:
await queryRunner.startTransaction()

try {
    // execute some operations on this transaction:
    await queryRunner.manager.save(user1)
    await queryRunner.manager.save(user2)
    await queryRunner.manager.save(photos)

    // commit transaction now:
    await queryRunner.commitTransaction()
} catch (err) {
    // since we have errors let's rollback changes we made
    await queryRunner.rollbackTransaction()
} finally {
    // you need to release query runner which is manually created:
    await queryRunner.release()
}

QueryRunner에는 트랜잭션을 제어하는 3가지 메소드가 있다.

1. startTransaction: 쿼리러너 인스턴스 내부에서 새로운 트랜잭션을 시작한다. 

2. commitTransaction: 쿼리러너 인스턴스를 사용하여 만들어진 모든 변경사항을 커밋한다.

3. rollbackTransaction: 쿼리러너 인스턴스에서 만들어진 모든 변경사항을 롤맥한다.

'프로그래밍 > TypeORM' 카테고리의 다른 글

[TypeORM] Delete using Query Builder  (0) 2023.09.02
[TypeORM] Insert using Query Builder  (0) 2023.09.02
[TypeORM] Caching queries  (0) 2023.08.31
[TypeORM] Active Record vs Data Mapper  (0) 2023.08.31
[TypeORM] Entity Inheritance  (0) 2023.08.31

댓글