-
Notifications
You must be signed in to change notification settings - Fork 0
Step 8: 비즈니스 Usecase 개발 및 통합 테스트 작성 #18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DB와 application의 타임존을 맞춰졌습니다.
|
||
private final PaymentCommandService paymentCommandService; | ||
|
||
@Transactional(readOnly = true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
파사드 계층에도 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
단순 쿼리로 해결 가능해보여서 작성했는데 객체지향에 맞게 도메인 레이어에서 작업하는게 좋았을까요?
@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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
흠 url 구조로인데 비슷한 로직이 3개가 되어버렸는데 더 좋은 방안이 있을지 의문이네요.
제출전 새벽에 짠거라... 다음에 더 고려해보겠숨다.
혹시 좋은 의견있으면 공유 부탁드림다.
@@ -9,6 +9,10 @@ public record GetConcertByIdParam(Long id) { | |||
|
|||
} | |||
|
|||
public record GetConcertByIdWithLockParam(Long id) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
env파일로 환경변수를 관리하였고 테스트 환경은 h2만 써도 괜찮을 것 같아서 분리하였습니다.
@@ -25,7 +26,7 @@ public class UserFacade { | |||
public Wallet chargeUserWalletAmount(Long userId, Long walletId, Integer amount) { | |||
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
해당 파사드 메소드에 @transactional을 다니까 영속성 컨텍스트가 관리되면서 lost update가 일어나는 것 같더라구요. (1차 캐시에서 데이터를 가져와서 그런지..)
이부분더 깊게 공부해봐야할 것 같은데 금요일날찾아보겠숨다... (혹시 아시면 힌트 부탁드림다.)
요구사항
작업 내용
리뷰포인트