본문 바로가기

전체 글

도메인주도개발 시작하기 8장 애그리거트 트랜잭션관리 8.1 애그리거트와 트랜잭션 한 주문 애그리거트에 대해 운영자는 배송 준비 상태로 변경할 때 사용자는 배송지 주소를 변경한다면 어떻게 될까 스레드는 각각 트랜잭션을 커밋할 때 수정한 내용을 DBMS에 반영함. 때문에 하나의 애그리거트를 여러 사용자가 동시에 변경하고자한다면 데이터의 일관성이 깨질 수 있음 이런 문제를 방지하기 위해서는 아래와 같은 방법을 사용해야 함 운영자가 배송지 정보를 조회하고 상태를 변경하는 동안 고객이 애그리거트를 수정하지 못하게 막는다. (Pessimistic) 운영자가 배송지 정보를 조회한 이후에 고객이 정보를 변경하면 운영자가 에그리거트를 다시 조회한 뒤 수정하도록 한다. (Optimistic) 낙관적락 : 충돌이 발생하지 않을거야 라고 낙관적으로 생각함 (비선점) -> 버전.. 더보기
Querydsl 방언 사용하기 Dialect JPA를 사용하면 데이터베이스 문법을 잘 알지 못해도 hibernate에 의해 설정한 데이터베이스의 쿼리로 바꿔준다. SQL,JPQL은 문자열인 반면 QUERYDSL을 사용하게 되면 java코드로 쿼리를 작성할 수 있게되고 컴파일 시점에 문법오류 를 확인할 수 있다는 큰 장점이 있다. application.yml에 사용하는 DB의 dialect가 설정되어있다. spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect FullText Search는 Dialect에 등록된 함수가 아니였기 때문에 querydsl 에서 사용할 수 없기 떄문에 별도로 커스텀해줘야한다. application.yml 설정 jpa: show-sql: true h.. 더보기
Redis - Pipelining Redis하면 뭐가 떠오를까 ? - 캐시이므로 빠른 성능 - key-value - 인메모리 db - Single thread - atomic Single thread vs Multi Thread redis는 부분적으로 Single thread와 Multi Thread를 함께 사용한다. 클라이언트로 부터 전송된 네트워크를 읽는 부분과 전송하는 부분은 Multi Thread로 구현되어있으며 우리가 redis에 요청한 명령을 실행하는 부분은 Single thread로 구현되어 있다. 때문에 single thread의 장점인 Atomic한 요청 처리가 가능한 것이다. I/O : 네트워크 connection Event Loop : 명령 실행부분 위와 같은 방식을 활용한다면 클라이언트가 네트워크 패킷을 여러번 보냈.. 더보기
mysql like함수 조회성능개선 mysql의 like함수를 사용하여 해당하는 키워드가 있으면 모두 필터링하여 가져오는 로직을 구현하였습니다. 하지만 like함수를 사용하게 되면 mysql은 full scan방식으로 데이터를 탐색하기때문에 성능이 안좋다는 것을 사전에 알고 있었기 때문에 직접 눈으로 확인해보고 싶었습니다. 또한 추후에 러닝커브가 높은 ealsticsearch를 통해 형태소 분석 및 사용자/동의어 사전을 통해 유사한 keyword가 들어왔을 때도 해당하는 단어를 출력해보고자 합니다. ElasticSearch는 왜 성능이 좋을지 먼저 알아보자 색인이 문서들에서 키워드를 뽑아낸다면, 역색인은 뽑아낸 키워드들을 바탕으로 그 키워드가 포함된 문서를 찾아나간다 쉽게 말하면 인덱스는 1페이지에 무슨단어 무슨단어 이런식으로 인덱스를 설.. 더보기
도메인주도설계 7장 도메인 서비스는 도메인 로직을 수행하지 응용 로직을 수행하진 않는다. 트랜잭션 처리와 같은로직은 응용로직이므로 도메인 서비스가 아닌 응용서비스에서 처리해야 한다. 특정 기능이 응용서비스인지 도메인 서비스인지 감을 잡기 어려울 때는 해당 로직이 애그리거트의 상태를 변경하거나 애그리거트의 상태 값을 계산하는지 검사해봐야한다. 예를 들어 계좌 이체 로직은 계좌 어그리거트의 상태를 변경하고 결제금액 로직은 주문 애그리거트의 주문금액을 계산한다. 두 로직은 각각 애그리거트를 변경하고 애그리거트의 값을 계산하는 도메인로직이다. 도메인 로직이면서 한 애그리거트에 넣기에 적합하지않으므로 이 두 로직은 도메인 서비스로 구현하게된다. 즉, 두개의 어그리거트의 상태값을 변경하는 것은 하나의 도메인로직에 넣기가 적합하지않으.. 더보기
도메인주도설계 6장 # 표현 영역과 응용 영역 - 응용 영역과 표현 영역이 사용자와 도메인을 연결해주는 매개체 역할을 함 - 표현 영역은 응용 서비스가 요구하는 형식으로 사용자 요청을 변환. - 응용 서비스를 실행한 뒤에 표현 영역은 실행 결과를 사용자에게 알맞은 형식(HTML/JSON)으로 응답 # 응용 서비스의 역할 & 주의점 응용 서비스는 사용자가 요청한 기능을 실행하는 영역을 담당한다. 이 때 리포지터리로부터 도메인 객첼르 구하고, 도메인 객체를 사용한다. 주의 사항은 응용 서비스에서 도메인 로직을 넣어서는 안된다. 응용 서비스에서 도메인 로직을 넣으면 두 가지 단점이 존재한다. 코드의 응집도가 떨어진다. 응용 서비스에서 동일한 도메인 로직을 구현할 가능성이 높아진다. (이는 실제로 몇 번 경험한 이슈) 도메인 로직.. 더보기
도메인주도설계 5장 CQRS : 명령 모델과 조회 모델을 분리하는 패턴. 상테(데이터) 변경 기능 구현시에는 명령 모델, 데이터를 보여주는 기능을 구현할 때는 조회 모델 사용 # 검색을 위한 스펙 스팩 Specification : 검색 조건을 다양하게 조합해야 할 때 사용할 수 있는 것 agg는 애그리거트 루트, agg는 검색 결과로 리턴할 데이터 객체가 됨. Spec 인터페이스 예시 Spec 인터페이스 구현 예시 만약 리포지터리가 메모리에 모든 애그리거트를 보관하고 있다면 다음과 같이 사용 가능하나, 실제로는 모든 데이터를 메모리에 저장을 못하기에 사실상 위와 같이 사용 불가능 실제 스펙은 사용하는 기술에 맞춰 구현하게 됨 # 스프링 데이터 JPA를 이용한 스펙 구현 JPA 크리테리아 API를 같이 이용 스펙은 and 혹.. 더보기
Spring jpa의 사실과 오해 우연히.. youtube를 보던 도중 NHN에서 올린 Spring JPA의 사실과 오해라는 알고리즘이 내 유튜브에 떳고 해당 영상을 시청하고 새롭게 알게된 지식을 다시한번 기록하기위해 작성하려고 합니다.ㅎㅎ 흔히 JPA를 통해 entity설계 및 로직을 구현해본사람이면 N+1문제는 알 것이빈다. 한번의 쿼리가 나갈 것을 예상하고 쿼리를 작성했는데 연관관계의 의해 N번의 쿼리가 추가적으로 나가는 것을 N+1이라고하는데 , 이것이 EAGER Fetch 타입뿐만아니라 lazy로딩에서도 발생될 수 있고, findAll과 같이 jpql이 먼저 수행되는 로직이 작성됐을 때도 발생할 수 있다는 이야기를 해주셨다. 위에 설명을 읽으니까 너무 이해가 잘 됐다. findAll같은 경우 단일 레코드 조회가 아닌경우, 해당 .. 더보기