간단한 자기소개와 2주차 후기입니다.
[들어가기 전]
다음 용어가 무엇인지 알고, 설명할 수 있나요?
AOP
, @Transactional
동작 원리안녕하세요! 주로 백엔드 개발을 하는 만 2년차 주니어 개발자 우이천입니다.
현업에서 주로 알림 컨텐츠/발송 기능을 맡고 있습니다. (SMS, 이메일등)
사실 점점 챕터가 힘들어질 것이라고 생각해서, 기본 개념들을 꼭 정립하고 가자
는 마음을 갖고 있었습니다!
그리고, 항해 하는 기간동안 일상을 건강하고 규칙적으로 보내보자! 라고 마음먹었구요. 항해가 끝나도 그 관성을 유지하고 싶었어요.
같은 팀원분들과 @Transactional
이 걸린 테스트를 디버깅하며 하루종일 고민했던게 가장 기억에 남습니다.
실제로 해당 어노테이션이 어떻게 동작하고, 어떨 때 쓰여야하는지 더 배웠습니다.
예를 들면, 왜 부모 메서드에 걸린 @Transactioanl은 전파되고, 안쪽에만 걸린 @Transactional은 부모에도, 안쪽에도 트랜잭션이 걸리지 않는걸까?에 대한 고찰
그러는 와중에 다양한 항플 구성원에게 도움을 구하고, 의견을 들었을 때도 기뻤습니다.
특히 코치님들이 정답을 알려주셨을 때 너무 기쁘면서 부끄러웠습니다. 아.. 내가 이런 것도 몰랐다고?
하는 감정과 이거 하루종일 봤는데 이걸 딱 해결해주시네
하는 감정이 복합적으로 몰려왔어요.
항플 코치 진짜 좋아요.
개쩔어요.
건강하게, 규칙적으로.. 지속가능하도록 성장하고 싶었어요.
근데 항해 플러스 백엔드에서 그런걸 기대하면 안될 것 같아요.
짧은 시간동안 고농축 동맥 주사 문도 박사형 성장하기에 트레이드 오프가 있다. 생각해주시는 게 더 좋아요! 😉
"주말 포함하여 최소 40시간정도 내줄 수 있는지?" 미리 생각해보시길 바랍니다.
항해에서 결국 뭐하겠어요? 코드 짜겠죠. 근데 그런 코드를 짜는 순간에 치열하게 고민했던 생각들이 사골 액기스마냥 성장 자체인 것 같습니다.
40시간? 어렵지 않네? 다시 생각해보세요.
평일 4시간정도는 공부하지 않는다면 현실적으로 불가능합니다.
그리고 이번 과제 주제가 뭐였지? 생각이 듭니다.
이번에도 기본 개념을 익힌다!
보다는 구현에만 급급했던게 아닐까 후회가 크게 남아요. 😅
도메인의 역할 설계에 좀 더 다양한 요구사항을 녹여내는 법
특히 이번 과제에서 비관락
을 이용해서 분산 환경에서 동시성을 제어하는게 크리티컬한 과제였는데, 실패했습니다.
깔끔한 도메인 설계를 지향해보려고 테이블 설계를 했는데, 치명적이게도 비관락을 전혀 고려하지 않은 설계였기 때문입니다.
어떻게 보면 당연하다. 부끄럽지만 한번도 현업에서 동시성 문제를 진지하게 고려해보지 않았으니까.
이제부터 배우면 된다. 개선해서 적용하면 된다.
현업에서 "엥 신청이 이상하다고요..? 그거 프론트쪽 문제 아니에요??" 안한게 어디야..
쪽팔리지 말자! 쪽팔려야 한다면, 미리 쪽팔리자!
여러분들은 다음 코드에서 왜 동시성 처리를 못할 수 밖에 없는지 알아차리셨나요?
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class RegisterService {
private final LectureService lectureService;
private final UserService userService;
private final RegisterRepository registerRepository;
@Transactional
public ApplyResponse apply(String userId, String lectureId, LocalDate date) {
LectureItem lectureItem = lectureService.findLectureItemByLectureIdAndDate(LectureId.of(lectureId), date);
User user = userService.findById(UserId.of(userId));
// 여기서 문제가 됨!
Register register = registerRepository.findByLectureItemId(lectureItem.getId()) //PESSIMISTIC WRITE 적용 (for update)
.orElse(new Register(LectureId.of(lectureId), lectureItem));
register.register(user);
registerRepository.save(register); //->10개의 `Register`가 생김..
return new ApplyResponse(userId, lectureId);
}
}
저는 이제 답을 알고 있습니다.. 메롱
시간 관리
결국 시간 싸움이다. 누가 해당 과제에 1초라도 더 고민해봤는지, 누가 한번이라도 더 작성한 코드를 엎어 봤는지, 멘토링 코치에게 뭘 물어봐야 하는지 한번이라도 더 고민하는 사람이 얻어가는게 많을 것이다.
멘탈 관리
그리고 멘탈 관리. 멘탈 나가지 말자. 어차피 끝까지 간 놈이 이기는거니까.
혹시 [들어가기전]의 답변이 궁금하신가요!?
글을 읽다보니 '아..! 나도 저거 알아야하는데!' 하진 않으신가요?!
여기까지 글을 읽으셨다면, 아마 항해 플러스 과정에 관심있으신 분이라고 생각합니다.
궁금한 점이 있으시다면 저에게 편하게 댓글 남겨주세요!!
혹은 highestbright98@naver.com
으로 메일을 남겨주셔도 굉장히 빨리 답변한답니다!
항해 플러스 백엔드에 관련해서 궁금하신점이 있다면 언제든 편하게 말씀주세요!
그리고 글이 도움됐다면, 등록하실때 제 추천인 코드 [9MPLfu] 입력하면,
20만원 할인의 혜택이 있답니다! (물론 저에게도 혜택이 있습니다! 😉)
우이천님 한주간 고생 많으셨습니다!! 같이 끝까지 달려보아요!