Jay's Cookbook
Menu
  • Tags
  • Categories
  • Projects
Computer Science
OS
Network
Data Structure
Algorithm
Language
Code Architecture
Python
Javascript
Typescript
Java
Backend
Backend Theory
TypeORM
Node.js
NestJS
FastAPI
Frontend
HTML/CSS
React
Next.js
Data Engineering
DE Theory
MySQL
MongoDB
Elastic
Redis
Kafka
Spark
Airflow
AI
Basic
Pytorch
NLP
Computer Vision
Data Analytics
Statistics
Pandas
Matplotlib
DevOps
Git
Docker
Kubernetes
AWS
[NestJS] 트랜잭션
backend
NestJS

[NestJS] 트랜잭션

Jay Kim
Jay Kim 05 Oct 2024
[NestJS] 로깅 [NestJS] 성능 최적화

Table of Contents


// src/common/interceptors/transaction.interceptor.ts
import {CallHandler, ExecutionContext, Injectable, InternalServerErrorException, NestInterceptor} from '@nestjs/common';
import { DataSource } from 'typeorm';
import { catchError, Observable, tap } from 'rxjs';

@Injectable()
export class TransactionInterceptor implements NestInterceptor {
  constructor(private readonly dataSource: DataSource) {}

  async intercept(
    context: ExecutionContext,
    next: CallHandler<any>,
  ): Promise<Observable<any>> {
    const req = context.switchToHttp().getRequest();
    req.isTransactional = true;

    const queryRunner = this.dataSource.createQueryRunner();
    await queryRunner.startTransaction();

    return next.handle().pipe(
      catchError(async () => {
        await queryRunner.rollbackTransaction();
        await queryRunner.release();
        throw new InternalServerErrorException(
          'Transaction is failed while creating book entity',
        );
      }),
      tap(async () => {
        await queryRunner.commitTransaction();
        await queryRunner.release();
      }),
    );
  }
}
// src/common/decorators/transaction.decorator.ts
import { createParamDecorator, ExecutionContext } from '@nestjs/common';

export const IsTransactional = createParamDecorator(
  (data: unknown, ctx: ExecutionContext) => {
    const req = ctx.switchToHttp().getRequest();
    return req.isTransactional;
  },
);


@UseInterceptors(TransactionInterceptor)
async createProduct(@Body() createProductDto: CreateProductDto, @IsTransactional() isTransactional: boolean) {
  return await this.productService.createProduct(createProductDto, isTransactional);
}

getProductRepository(isTransactional: boolean) {
  if (isTransactional) {
    const queryRunner = this.dataSource.createQueryRunner();
    return queryRunner.manager.getRepository(ProductEntity);
  }
  return this.productRepo;
}

async createProduct(createProductDto: CreateProductDto, isTransactional: boolean) {
  const repo = this.getProductRepository(isTransactional);
  const product = repo.create(createProductDto);
  return await repo.save(product);
}
[NestJS] 로깅 [NestJS] 성능 최적화

You may also like

See all NestJS
14 Oct 2024 [NestJS] API 문서화
backend
NestJS

[NestJS] API 문서화

09 Oct 2024 [NestJS] SSE
backend
NestJS

[NestJS] SSE

08 Oct 2024 [NestJS] 웹 소켓
backend
NestJS

[NestJS] 웹 소켓

Jay Kim

Jay Kim

Web development, data engineering for human for the Earth. I share posts, free resources and inspiration.

Rest
Lifestyle
Hobby
Hobby
Hobby
Hobby
2025 © Jay's Cookbook. Crafted & Designed by Artem Sheludko.