- TypeOrm 에서 Transaction 작성 방법은 총 3가지가 존재
getConnection() / getManager() 을 이용
import {getConnection} from "typeorm";
await [getConnection() / getManager()].transaction("SERIALIZABLE", async transactionalEntityManager => {
await transactionalEntityManager.save(users);
await transactionalEntityManager.save(photos);
});
- DB 에 접근할 떄에는 무조건!!
transactionalEntityManager 을 이용해서 접근해야 한다.
- isolation level 은 첫 번째 매개변수로 넘겨줄 것.
@Transaction decorator를 이용
@TransactionManager 를 이용하여 쿼리 작성
@Transaction({ isolation: "SERIALIZABLE" })
async createUser(
@TransactionManager() manager: EntityManager,
user: User,
verification: Verification,
) {
await manager.save(user);
await manager.save(verification);
}
@TransactionRepository(user) 를 이용하여 쿼리 작성
@Transaction()
save(user: User, @TransactionRepository(User) userRepository: Repository<User>) {
return userRepository.save(user);
}
save 함수를 사용할 때에, 인자로 들어온 @TransactionManager() manager OR TransactionRepository(User) 는 매개변수로 넘겨줄 필요가 없다.
- 자동으로 넘겨온다
- 하지만 해당 함수를 사용할 때
Expected 3 arguments, but got 2. 라는 Typescript Error 가 발생 ( → 어떻게 하면 에러없이 사용할 지 알아 볼 것 )
- 제일 맘에 드는 방식
- 첫 번째 방법인
getConnection() / getManager() 를 사용하는 방식에선, callback을 사용하기 때문에 가독성이 좋지 않고
- 세 번째 방법인
queryRunner 를 사용하는 방식에선, COMMIT / ROLLBACK / RELEASE 를 계속해서 작성해야 하기 때문에 귀찮다
queryRunner 를 이용
const queryRunner = getConnection().createQueryRunner();
try {
const userEntity = this.users.create({ email, password, role });
const verificationEntity = this.verification.create({
code: '1231231',
user: userEntity,
});
queryRunner.startTransaction();
await queryRunner.manager.save(userEntity);
await queryRunner.manager.save(verificationEntity);
queryRunner.commitTransaction();
return { ok: true };
} catch (error) {
queryRunner.rollbackTransaction();
} finally {
queryRunner.release();
}
좋은 포스팅감사합니다.
하지만 해당 함수를 사용할 때 Expected 3 arguments, but got 2. 라는 Typescript Error 가 발생 ( → 어떻게 하면 에러없이 사용할 지 알아 볼 것 )해당 사항은 옵셔널로 구성하면됩니다.