목록전체 글 (9)
사부작사부작
틀린 부분이 존재할 수 있습니다. 감사합니다. 객체는 그래프로 연관된 객체들을 탐색한다. 그런데 객체가 데이터베이스에 저장되어 있으므로 연관된 객체를 마음껏 탐색하기는 어렵다 - 김영한 JPA는 연관된 객체들을 탐색하는 것을 도와준다. JPA는 직접 쿼리를 날려서 연관된 객체의 데이터를 가져온다. 예를 들어 고객과 주문으로 이루어진 1:N 구조에서 1번 고객이 3건의 주문을 한 데이터가 있다고 하자. 이 상태에서 1번 고객에 연관된 주문 객체들을 가져올 때, 주문 3건에 대해 각각 쿼리를 날려서 가져온다. 그렇기에 흔히 말하는 N+1 쿼리가 발생한다. 그렇다면 JPA는 왜 쿼리를 N번이나 날려서 연관된 객체들을 조회해올까? 왜 JPA는 조인을 통해 고객을 조회할 때 연관된 주문 데이터들을 가져오지 않을까..
OSIV 를 default 값인 true인 상태로 개발을 하다가, false로 바꾸고 이에 따른 더티 체킹이 작동하지 않는 문제를 겪었습니다. OSIV에 대한 설명과 개선해 간 과정을 적은 글입니다. 틀린 부분이 있을 수 있습니다. 먼저 OSIV를 모르는 상태로 기능을 구현하는 중이였다. 그러다가 동욱님의 블로그 글(jojoldu.tistory.com/272)을 읽다가 OSIV라는 단어를 접했고, 이걸 false로 변경하기로 했다. OSIV (Open-Session-In-View) OSIV는 Hibernate 세션(DB작업을 수행하기 위한 논리적 트랜잭션 컨텍스트)을 뷰까지 열어두는 패턴을 의미한다. 스프링에서 이 패턴을 구현한 클래스로는 OpenSessionInViewInterceptor 클래스가 있다..
본 글은 AOP로 기능 구현한 내용을 다루는 글입니다. 개념적인 설명이 미흡할 수 있고, 틀린 부분이 존재할 수 있습니다. 피드백 해주시면 정말 감사하겠습니다 :) 어플리케이션 전반에 퍼져있는 공통된 부가 기능들을 관심사(Aspect)라고 한다. 우리가 널리 쓰고 있는 트랜잭션이 Aspect의 예다. 트랜잭션이 필요한 메서드마다 트랜잭션을 얻고 커밋과 롤백 등의 로직을 구현해야 한다면, 코드가 복잡해질 것이다. 이처럼 비지니스 로직과 달리 부가적으로 들어간 기능을 관심사(Aspect)라고 정의하고 이를 비지니스 로직에서 분리시킬 것이다. Aspect Oriented Programming(AOP) OOP는 비즈니스 로직의 중복을 제거하기 위함이고 AOP는 인프라 로직 중복을 제거하기 위함이다. 여기서 인프..
분산락이 필요한 상황 설명 유저들이 검색한 검색어를 Redis의 Sorted Set에 저장하고, 그걸 바탕으로 인기 검색어를 구현했다. 검색될 때마다 Redis에 저장시켰는데, 통신부하를 줄여보기 위해서 검색어를 서버에 리스트 안에 모아서 100개가 되면 Redis에 보내게 바꿨다. 지금 내 토이프로젝트 상황으로는 검색어 100개를 모으려면, 100일은 더 걸릴 것이다. (사용하는 유저가 없다..ㅠ) 그렇기에 100개가 안 되더라도 Redis에 저장시키기 위해서, 스케줄러로 하루에 2번씩 모아진 검색어를 저장시키게 했다. 하지만 문제가 발생했다! 왜냐하면 난 2대의 서버를 운영중이기 때문이다. 2대의 서버가 동시에 레디스로 데이터를 보내는데 여기서 동시성 이슈가 터졌다. 검색한 검색어 일부가 Redis에..
페이지네이션 구현 페이지네이션은 데이터를 페이지 단위로 나누어 화면에 보여주는 기능이다. 전체 데이터가 아니라 필요한 페이지의 데이터만 불러오기 때문에 성능을 향상시킬 수 있다. 물론 사용자 경험도 훨씬 좋다. 밑의 화면처럼 페이지네이션을 화면에 만들기 위해선 토탈 페이지 카운트를 알아야한다. 그렇기에 페이지네이션이 이루어지려면 페이지당 몇 개의 데이터를 보여줄건지와 토탈 페이지 카운트를 알려줘야 한다. 내 프로젝트의 프론트엔드는 컴포넌트를 이용해서 페이지네이션을 구현했다. 여기서 보다시피 length 속성으로 토탈 페이지 카운트를 입력받고 있다. 프론트엔드에서 전체 데이터 개수로 토탈 카운트를 구할 수 있지만, 백엔드에서 토탈 카운트를 보내주는게 일반적이다. 백엔드에서는 Pageable 인터페이스를 구..
이 글은 토이 프로젝트를 만들며 사용된 AWS 서비스들의 역할과 배포 흐름을 써보려 합니다. 더불어 왜 oAuth 인프라를 분리했는지도 마지막에 다루겠습니다. 틀린 설명이 존재할 수 있습니다. 발견하시면 피드백 부탁드립니다. 토이 프로젝트 : books4dev.me 2개의 Availity Zone(AZ)으로 나눈 Multi AZ로 구성을 했다. 각 AZ마다 운영에 사용되는 서버를 배치했다. 그리고 Load Balancer를 둬서 각각 서버가 다른 요청을 처리하게 했다. 즉, 분산 환경이다. 2대의 웹 애플리케이션 서버(WAS)를 기본적으로 운영하고 있으며, Auto Scaling을 이용하여 필요에 따라 서버를 동적으로 확장할 수 있도록 구성했다. 각각의 WAS들은 도커 위에서 운영중이다. Single A..
안녕하세요. books4dev.me 를 기획하고 개발했습니다. 기획과정을 회고해 보겠습니다. 어떻게 기획을 하게 됐는지 적어보겠습니다. 1. 아이디어 지금으로부터 2년 전인, 2021년 4월에 머릿속에 아이디어가 떠올랐다. 개발 도서를 언제 읽는 게 좋은지 추천해 줄 수 있게 하자. 그리고 추천 시기를 차트로 만들어서 책과 함께 보여주자. 그러면 도움이 될 것 같은데? 더불어서 추천 시기를 등록할 때, 언제 읽었는지도 유저에게 받자. 유저가 이 책을 언제 읽었는지 받은 거는 마이페이지에서 역사책에 나오는 연대기 느낌으로 보여주자 이런 생각과 웹사이트 화면들이 머릿속에서 스쳐 지나가듯 생각난 것이다. 당시에 나는 3개월 기간의 부트캠프를 수료하고 동기들과 공유오피스에서 취준 및 공부를 할 때였다. 난 부트..
Intro @Builder 어노테이션이 편리하여 자주 사용했습니다. 어느날, 생성한 객체가 초기값이 아니라 Null 값이 나오면서 왜 Null 이 나온건지, 어떻게 해결할 수 있을지 고민했습니다. 비슷한 경험이 있으신 분들에게 아래 글이 도움이 되길 바랍니다. 틀린 내용이 있을 수 있습니다. 피드백 해주신다면 감사하겠습니다. 롬복의 @Builder 를 사용하면, 빌더패턴을 구현할 수 있고 간단하게 객체를 생성할 수 있다. 하지만 편리한 @Builder 어노테이션을 클래스 위에 사용할땐 주의할 점이 있다. 먼저 예시 코드는 블로그 클래스와 유저 클래스로, 유저가 여러개의 블로그를 쓸 수 있는 1:N 구조다. @NoArgsConstructor(access = AccessLevel.PROTECTED) @All..
Intro 영속성 컨텍스트가 무엇인지, 왜 사용하는지, 어떤 방식으로 작동하는지에 중점을 두고 쓴 글 입니다. 이 글에 나오는 엔티티 생명 주기, 식별자 생성 전략 등 다른 개념들은 깊게 다루지 않습니다. 틀린 내용이 있을 수 있습니다. 피드백 해주신다면 너무 감사하겠습니다. # 프로그래밍에서 Context 먼저 컨텍스트를 살펴보자. 서블릿 컨텍스트, 영속성 컨텍스트 등 컨텍스트는 여러 곳에서 쓰인다. '문맥', '맥락' 이라는 사전적 뜻에 의해 위 단어들이 느낌은 오지만 쉽게 이해되지는 않았다. 찾아보다가 CTO 님께 질문을 드렸고, 답을 얻었다. Task는 운영체제 상에서 실행되는 작업의 단위라고 한다면, Context는 해당 Task의 정보를 메모리 등에 저장하여 관리하기 위한 단위 정도라면 도움이..