🔔[항해99]/WIL

[항해플러스 백엔드후기] 2주차 회고 - 비관적 Lock도 락이다

디카페인라떼 2024. 12. 28. 20:38

 

[개요]

어느새 폭풍같이 1주일이 지나가고 벌써 2주차가 다가왔다. 

퇴근후 매일 과제를 하느라 새벽 2,3시에 자고 다시 야근하고 공부하는 일주일이었다.. 이렇게 이제 9주만 더하면 된다! 

 

이번 과제가 수강신청 시스템에서 동시성 이슈를 생각해야 하는데 

매번 티켓팅하면서 동시성때문에... 이선좌 화면을 봤던 기억이 떠올랐다.. 

이번 과제와 비슷하게 DB 락을 걸어서 해당 좌석 자체를 락을 걸어버렸기에 내가 그 콘서트를 못갔던 거겠지..

[과제]

2주차의 과제는 이러했다. 

* 기본기능

- 아키텍처 준수를 위한 애플리케이션 패키지 설계
- 특강 도메인 테이블 설계 (ERD) 및 목록/신청 등 기본 기능 구현
- 각 기능에 대한 **단위 테스트** 작성

* STEP 3

- 설계한 테이블에 대한 **ERD** 및 이유를 설명하는 **README** 작성
- 선착순 30명 이후의 신청자의 경우 실패하도록 개선
- 동시에 동일한 특강에 대해 40명이 신청했을 때, 30명만 성공하는 것을 검증하는 **통합 테스트** 작성

* STEP 4

- 같은 사용자가 동일한 특강에 대해 신청 성공하지 못하도록 개선
- 동일한 유저 정보로 같은 특강을 5번 신청했을 때, 1번만 성공하는 것을 검증하는 **통합 테스트** 작성

 

 

  • 이번에는 스켈레톤 코드가 주어지지 않고 자유 구현이었다. 자유도가 높은 만큼 걱정도 많았다. 
  • 이번 주제는 클린 아키텍쳐인 만큼 패키지 구조 설계부터도 중요했다
  • 수강신청 서비스인만큼 동시성 이슈를 고려해 구현해야한다. 하지만 이번부터는 DB를 연동해 서비스를 구현해야 한다.
    • 특강을 신청하는 요청을 선착순으로 성공시켜야 한다는 점과 동일한 아이디의 사용자가 동일한 특강에 대해 한 번만 성공하게 구현해야 하는 점이 관건 

 

[과제 해결 과정]

  1. 클린-레이어드 아키텍처에는 정답이 없다. 중요한건 DIP 라고 생각했다
    • 의존 관계를 맺을 때 자신보다 변화하기 쉬운 것을 의존해서는 안 되고, 거의 변화가 없는 개념에 의존해야 한다 는 개념으로 생각했다
    • 사실 생각할수록 어려워져서 제일 나에게 익숙한 MVC 구조로 구현하고 나중에 패키지를 바꾸어 주었다. 
  2. 요구사항에 부합하는 DB 설계
    • Lecture와 LectureSchedule의 분리
      • 주요 요구사항에 따라 특강은 제목, 내용, 강사를 가지며 여러 개의 스케줄을 가질 수 있습니다. 따라서 특강 정보를 관리하는 Lecture 테이블과 일정 정보를 관리하는 LectureSchedule 테이블을 분리 설계했다
    • Lazy Join 적용
      • LectureSchedule과 UserLectureHistory 등 엔티티 간 연관 관계에서 필요하지 않은 데이터를 즉시 로딩하지 않고 지연 로딩을 설정하여 성능을 최적화했다요구사항에 부합하는 DB 설계
  3. 기본 기능 API 구현 + 단위 테스트 코드 작성
  4. 동시성 제어를 위한 DB 락설정 
    • JPA에서 제공하는 DB Lock 중 Pessimistic Lock (비관적 락)을 사용하여 동시성 제어를 구현하였다.
    • 특히 특강 신청 과정에서 여러 사용자가 동시에 정원을 초과해 신청하는 상황을 방지하고 current_capacity 값을 정확히 관리하기 위해 적용했다. 이를 통해 트랜잭션 중 다른 사용자가 동일 데이터를 수정하지 못하도록 하여 데이터 충돌을 효과적으로 예방할 수 있었다.
  5. 통합테스트 작성 

 

[알게된 것]

  • 비관적 락(PESSIMISTIC_WRITE)의 중요성과 사용 방법
    • 동시성 문제를 제어하며 데이터 무결성을 유지하기 위해 비관적 락을 활용할 수 있음을 배웠다
    • @Lock 어노테이션과 JPA의 EntityManager를 활용하여 락을 구현하는 방식을 학습했다
  • 지연 로딩(Lazy Loading)의 성능 최적화 효과
    • 엔티티 간 연관 관계에서 불필요한 데이터를 로딩하지 않도록 FetchType.LAZY를 활용한 설계의 중요성을 이해.
  • 효율적인 테이블 설계
    • ERD 설계에서 중복 데이터와 관계를 최소화하여 관리와 확장성을 높이는 방법을 학습.
    • 특강과 특강 스케줄을 분리하여 유지보수성을 고려한 데이터베이스 설계.

 


이번주 KPT 회고


Keep : [유지해야 할 좋은 점]

- 요구사항 분석을 하고 체크리스트로 정리하니 좀더 보기에 편하고 구현에 빠짐이 없어 좋았다 

- 객체 지향적인 클린 코드를 작성하기 위해 노력했는데 비즈니스 로직이 깔끔해져서 칭찬을 받았다! 클린 코드에 대한 열정을 유지하자....


Problem : [개선이 필요한 점]

- 아직 클린 아키텍처 패키지 구성이 부족한 것 같다. 변수명이나 테스트 명도 좀더 명확하게 사용하는 것이 필요하다 


Try : [새롭게 시도할 점]

- 패키지 구조 잘 구성하기 

- 변수명이나 메소드명에 대해서 좀더 명확히 하자 . 남이 보기에 쉬운 코드를 작성하자 

 


 

 

이번 과제에서 BP 따봉을 받게 되었다. 1도 상상못했던 터라 코치님의 피드백을 보고는 더욱더 열심히 해야겠다는 의지를 다졌다

 

챕터 2가 끝나고 이번에도 무사히 과제 2개 모두 PASS를 해서 전체 과정중 20%를 완료하여 블루 배지를 획득하였다.

과정을 진행 할수록 게임 처럼 레벨업을 하는 기분이어서 과제를 해나갈 수록 점점 더 욕심이 생긴다

좀더 열심히 해야지 ..! 연말연시 바쁘지만 쪼개고쪼개서 잘 해내보자 ~~