코드
user.service.ts
// imports 생략
// User 엔티티 와 dto 코드 생략
@Injectable()
export class UserService {
constructor(
private dataSource: DataSource,
@InjectRepository(User) private userRepository: Repository<User>,
private readonly configService: ConfigService,
private readonly authService: AuthService,
) {}
// 동시성 문제를 테스기하기 위해 추가
delay(ms: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, ms));
}
async signUp(signUpRequestDto: SignUpRequestDto): Promise<any> {
const { password, email, name } = signUpRequestDto;
const queryRunner = this.dataSource.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
// lock 사용 -> 다른 트랜잭션이 같은 이메일의 사용자를 생성하는 것을 방지
// pessimistic_write : 데이터를 처음 읽을 때 락을 걸고 트랜잭션이 끝날 때까지 락을 유지하는 방법 사용
let user = await queryRunner.manager.findOne(User,
{ where: { email }, lock: { mode: 'pessimistic_write' } });
if (user) {
throw new Error('Email already exists');
}
const saltRounds = this.configService.get<string>('SALT_ROUNDS');
if (saltRounds === undefined) {
throw new Error('SALT_ROUNDS is not defined in the configuration.');
}
const hashedPassword = await bcrypt.hash(password, parseInt(saltRounds));
user = new User({ name, email, password: hashedPassword });
await this.delay(5000); // 동시성 문제를 테스기하기 위해 추가
const newUser = await queryRunner.manager.save(user);
await queryRunner.commitTransaction();
return new SignUpResponseDto({ ...newUser });
} catch (error) {
await queryRunner.rollbackTransaction();
throw error;
} finally {
// 리소스 해제 필수
await queryRunner.release();
}
}
}
Postman 을 이용하여 같은 유저 데이터를 전송한 결과
첫번째 요청
{
"id": 1,
"email": "test_lock@email.com",
"name": "Tester"
}
두번째 요청
{
"statusCode": 500,
"message": "Internal server error"
}
- console 화면
'프로그래밍 > Nest.js' 카테고리의 다른 글
[ Nest.js ] insert vs save : 둘 이상의 데이터 저장시 속도비교 (1) | 2024.07.22 |
---|---|
[ Nest.js ] Middleware, Guard, Interceptor, Pipe, Filter (0) | 2024.07.20 |
[ Nest.js ] cross-validator 의 데코레이터가 적용이 안되는 경우 (0) | 2024.07.14 |
[ Nest.js ] [ TypeORM ] bulk insert (0) | 2024.07.06 |
[ Nest.js ] cross-validation 을 이용하여 데코레이션 만들기 (0) | 2024.07.03 |