Step 8: 비즈니스 Usecase 개발 및 통합 테스트 작성#18
Conversation
kilhyeonjun
left a comment
There was a problem hiding this comment.
usecase별로 PR을 분리했으면 좋았을 것 같은데 시간상의 이유로 하나의 PR에 커밋단위로 분리했습니다. 🥲
query command 객체의 validation에 대한 테스트를 작성해주는 게 맞을지 의문이에요.
생각보다 생산성이 많이 떨어지는 것 같습니다.
| public class HhplusConcertApplication { | ||
|
|
||
| public static void main(String[] args) { | ||
| TimeZone.setDefault(TimeZone.getTimeZone("UTC")); |
There was a problem hiding this comment.
DB와 application의 타임존을 맞춰졌습니다.
|
|
||
| private final PaymentCommandService paymentCommandService; | ||
|
|
||
| @Transactional(readOnly = true) |
There was a problem hiding this comment.
파사드 계층에도 Transactional 이 필요할지 의문이네요.
롤백이 필요한 경우를 제외하고는 안쓰는 게 좋을까요?
롤백을 안쓴다면 영속성 컨텍스트로 인해 캐싱되는 부분의 이점을 가져가면 가는걸까요?
| @Modifying(clearAutomatically = true) | ||
| @Query("UPDATE WaitingQueue wq SET wq.status = 'EXPIRED' WHERE wq.status = 'PROCESSING' AND wq.expiredAt <= CURRENT_TIMESTAMP") | ||
| void expireWaitingQueues(); |
There was a problem hiding this comment.
단순 쿼리로 해결 가능해보여서 작성했는데 객체지향에 맞게 도메인 레이어에서 작업하는게 좋았을까요?
| @Transactional(readOnly = true) | ||
| public void validateWaitingQueueProcessingAndConcertId(String waitingQueueUuid, Long concertId) { | ||
| WaitingQueue waitingQueue = waitingQueueQueryService.getWaitingQueue( | ||
| new GetWaitingQueueByUuid(waitingQueueUuid)); | ||
|
|
||
| waitingQueue.validateProcessing(); | ||
| waitingQueue.validateConcertId(concertId); | ||
| } | ||
|
|
||
| @Transactional(readOnly = true) | ||
| public void validateWaitingQueueProcessingAndScheduleId(String waitingQueueUuid, | ||
| Long scheduleId) { | ||
| WaitingQueue waitingQueue = waitingQueueQueryService.getWaitingQueue( | ||
| new GetWaitingQueueByUuid(waitingQueueUuid)); | ||
| waitingQueue.validateProcessing(); | ||
|
|
||
| ConcertSchedule concertSchedule = concertQueryService.getConcertSchedule( | ||
| new GetConcertScheduleByIdQuery(scheduleId)); | ||
| waitingQueue.validateConcertId(concertSchedule.getConcertId()); | ||
| } | ||
|
|
||
| @Transactional(readOnly = true) | ||
| public void validateWaitingQueueProcessingAndSeatId(String waitingQueueUuid, Long seatId) { | ||
| WaitingQueue waitingQueue = waitingQueueQueryService.getWaitingQueue( | ||
| new GetWaitingQueueByUuid(waitingQueueUuid)); | ||
| waitingQueue.validateProcessing(); | ||
|
|
||
| ConcertSeat concertSeat = concertQueryService.getConcertSeat( | ||
| new GetConcertSeatByIdQuery(seatId)); | ||
| ConcertSchedule concertSchedule = concertQueryService.getConcertSchedule( | ||
| new GetConcertScheduleByIdQuery(concertSeat.getConcertScheduleId())); | ||
| waitingQueue.validateConcertId(concertSchedule.getConcertId()); | ||
| } |
There was a problem hiding this comment.
흠 url 구조로인데 비슷한 로직이 3개가 되어버렸는데 더 좋은 방안이 있을지 의문이네요.
제출전 새벽에 짠거라... 다음에 더 고려해보겠숨다.
혹시 좋은 의견있으면 공유 부탁드림다.
|
|
||
| } | ||
|
|
||
| public record GetConcertByIdWithLockParam(Long id) { |
There was a problem hiding this comment.
Param 객체를 이용해서 오버로딩을 사용했습니다.
repository 메소드 네이밍은 간결해졌으나 Param객체 자체의 네이밍이 길여져서 고민이네요.
| config: | ||
| activate: | ||
| on-profile: local | ||
| datasource: | ||
| url: jdbc:mysql://${DB_HOST}/${DB_NAME}?characterEncoding=UTF-8&serverTimezone=UTC | ||
| username: ${DB_USERNAME} | ||
| password: ${DB_PASSWORD} | ||
| driver-class-name: com.mysql.cj.jdbc.Driver |
There was a problem hiding this comment.
env파일로 환경변수를 관리하였고 테스트 환경은 h2만 써도 괜찮을 것 같아서 분리하였습니다.
| var user = userQueryService.getUser(new GetUserByIdQuery(userId)); | ||
|
|
||
| var wallet = userQueryService.getWallet(new GetUserWalletByUserIdQuery(user.getId())); | ||
| var wallet = userQueryService.getWallet(new GetUserWalletByUserIdWithLockQuery(user.getId())); |
There was a problem hiding this comment.
해당 파사드 메소드에 @transactional을 다니까 영속성 컨텍스트가 관리되면서 lost update가 일어나는 것 같더라구요. (1차 캐시에서 데이터를 가져와서 그런지..)
이부분더 깊게 공부해봐야할 것 같은데 금요일날찾아보겠숨다... (혹시 아시면 힌트 부탁드림다.)
요구사항
작업 내용
리뷰포인트