현재 진행중인 프로젝트에서 게시글을 삭제 할 때 게시글의 id를 배열로 받아와서 처리 중이다.
처음 로직을 짤 때는 Promise.all 만을 사용하여서 처리를 하였는데 생각을 해보니 중간에 이상한 id값이 들어 오는 등 예외상황을 생각해서 처리를 해주어야 할 것 같아 트렌젝션을 추가하기로 하였다.
참고 : TypeORM-Transaction
현재 코드
await Promise.all(idArr.map(async id => {
if(typeof id !== 'number') throw new BadRequestException('공지사항의 아이디를 정확히 보내주세요.');
const result = await this.faqRepository
.createQueryBuilder()
.update(Faq)
.set({deletedAt: new Date()})
.where('id = :id', {id})
.execute();
if( result.affected === 0 ) {
throw new BadRequestException('존재하지 않는 게시글 입니다.');
}
}))
공식 문서
// 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()
}
수정 후 코드
async deleteFaq(idArr: BigInt[]) {
const queryRunner = this.connection.createQueryRunner();
await queryRunner.connect(); // 2
await queryRunner.startTransaction(); // 3
try {
await Promise.all(idArr.map(async id => {
const result = await queryRunner.manager.delete(Faq, {id});
if( result.affected === 0 ) {
throw new BadRequestException('존재하지 않는 게시글 입니다.');
};
}))
// 삭제 도중 잘못된 id가 들어올 경우 transaction 롤백
} catch (error) {
await queryRunner.rollbackTransaction();
await queryRunner.release();
throw new BadRequestException('존재하지 않는 게시글 입니다.');
}
// 모든 아이디가 정상 적일 경우 transaction commit
await queryRunner.commitTransaction();
await queryRunner.release();
}