spring/JPA
-
Spring Hibernate + Redis + MailSender 트랜잭션 동기화spring/JPA 2021. 5. 24. 11:31
배경 현재 프로젝트에서 사용자가 회원가입을 한 경우 흐름을 보면 DB에 사용자 저장(Hibernate) -> 인증코드 생성 후 이메일로 전송(MailSender) -> Redis에 이메일(key)+인증코드(value) 저장하는 로직이다. 이후 사용자 인증을 시도한 경우 Redis에서 데이터를 찾아 인증을 확인 후 사용자의 권한을 업그레이드한다. 흐름은 크게 3가지로 나뉘고 이 3가지 흐름은 원자적으로 묶여야 한다. 즉, 하나라도 실패한 경우 전부 실패해야하고 성공한다면 전부 성공해야 한다. 트랜잭션과 예외처리를 통해 간단하게 세 프로세스를 원자적으로 묶어보자. 상황 분석 1) redis에 우선 Hello를 key로, World를 value로 저장한다. 2) Hibernate로 member를 저장한다. 3..
-
Spring 다중 데이터소스 설정 및 트랜잭션 동기화spring/JPA 2021. 5. 23. 17:53
배경 서비스 규모가 작다면 한 애플리케이션에서 보통 한 DB리소스만 사용한다. 어떤 경우는 둘 이상의 DB접근이 필요한 경우도 있고 서로 다른 두 DB서비스를 논리적인 트랜잭션 단위로 묶어 작업을 원자적으로 처리할 필요가 있다. 심지어 DB가 아니더라도 JMS와 같은 서비스 또한 한 트랜잭션 단위로 묶일 필요가 있다. 이번 글에서 위 2가지 경우를 예제로 작성해보고 정리해보자. 1. 한 애플리케이션에서 두개의 DB 연결 2. 두 DB의 작업을 트랜잭션으로 묶어서 처리하기 배경지삭 쌓고 가기 - 로컬 트랜잭션 : 하나의 DB커넥션 안에서 말들어지는 트랜잭션 - 트랜잭션 경계설정 : autoCommit를 false로 설정한 뒤 commit 또는 rollback을 원하는 시점에 호출 - PlatformTran..
-
연관관계 주인 mappedBy 끝내기spring/JPA 2021. 5. 5. 12:49
배경 cascade 옵션을 공부하면서 양방향 연관관계에서 mappedBy개념을 정리했지만 매번 헷갈린다. 예제를 작성하며 완전히 알고 넘어가보자! 개념 RDB는 양방향 연관관계라는 개념이 없다. 단지 한 테이블이 연관테이블의 FK를 가질 뿐이다. FK는 두 테이블 중 한 테이블만 갖고 있다. 반면 JPA는 양방향 연관관계라는 개념이 있다. 이는 레코드를 객체처럼 관리하기 위함이다. RDB는 조인을 이용해 언제든지 다른 테이블을 참조할 수 있지만 상대 객체의 정보가 없는 객체는 연관 객체를 참조할 수 없다는 점을 보완한 것이다. 엔티티를 설계하면서 연관된 두 엔티티를 단방향으로 설계했다면 딱히 문제될 건 없다. 실제로 양방향보다 단방향으로 관계를 갖는 게 자연스러운 경우가 많다. 그럼에도 양방향으로 관계를..
-
JPA 다른 모듈에서 ENTITY 스캔하기spring/JPA 2021. 4. 29. 08:59
배경 마이크로 서비스를 구축하면서 서비스와 서비스를 연결할 때 공통으로 필요한 코드는 모듈로 분리했다. 일명 라이브러리모듈로서 main은 없고 적절히 import만 할 수 있게 만든 것이다. 이러면 공통적으로 사용하는 코드를 한 모듈에서 관리하니 유지보수성이 크게 올라간다. 그렇다면 어떤 코드가 이 라이브러리모듈에 들어가야 할까? 아직 노하우가 많지 않아 정확한 판단을 하기는 어렵지만 작은 경험으로 추측해보았다. 먼저 DTO 같은 경우 큰 논란 없이 라이브러리모듈에 들어가도 될 것 같다. 다음으로 @Entity애노테이션이 붙은 도메인클래스를 생각해봤다. 한 서비스에서 하나의 도메인만 다루더라도 연관관계가 얽혀 있다면 다른 도메인이 필요할 것이다. 결국 완성된 데이터는 한 서비스에서 조립되어 전달되니 도메..
-
JPA open session in view 설정하기spring/JPA 2021. 4. 8. 17:00
배경 영속성컨텍스트에 대해 어느정도 이해했다고 자만하고 있었다. 강의를 보며 지연로딩된 엔티티를 Controller에서 불러오는 경우가 있었는데 어라?정도로만 넘어가고 깊게 생각해보지 않았다. 직관적으로는 당연히 영속성컨텍스트는 서비스로직의 트랜잭션과 생명주기를 같이 할줄 알았다. 강의 막바지에 open session in view(osiv)에 대해 배웠고 그 내용을 정리한다. yml에 설정하기 osiv에 대한 아무런 설정 없이 was를 실행시키면 위와 같은 warn로그가 나온다.(있는 줄도 몰랐다) 내용을 보면 osiv는 기본이 true이고 db는 view를 랜더링할 때도 실행되며 이 경고창을 없애려면 osiv를 disable하라는 내용이다. 영속성컨텍스트는 트랜잭션 시작과 동시에 활성화 된다. 이때 ..
-
JPA와 하이버네이트 N+1 최적화 과정spring/JPA 2021. 4. 8. 16:21
배경 진행하는 프로젝트의 테이블이 단순해서 그런지 JPA 성능 이슈를 겪어본 적이 없다. 강의를 들어며 강조한 N+1문제도 딱히 그러려니 한데 워낙 강조되는 내용이기도 하고 왜 중요한지도 이해한 상태다. 다만, 써먹을 일이 없다보니 자꾸 까먹으니 정리해두자. ToOne에서 최적화 관계가 ToOne이라면 이미 best solution이 있다. 그냥 바로 join fetch를 쿼리 안에 녹이는 방법이고 이는 사실 RDB와도 직관적으로 다르지 않다. 잘 생각해보면 어렵지 않으니 간단하게 넘어가자. 컬렉션 최적화 컬렉션에서 최적화를 하려면 케이스 별로 다르게 최적화를 해야 한다. 단 하나의 컬렉션만 포함하며 페이징이 필요 없는 경우 이 경우는 ToOne과 마찬가지로 join fetch를 적용하면 되는데 단 di..
-
-
양방향 연관관계와 CASECADE 옵션spring/JPA 2021. 2. 25. 00:56
프로젝트를 진행하던 중 게시글 입력 규칙을 바꾸기로 했다. 기존 게시글은 본인의 이력을 입력하는 필드가 있었는데 이 입력 필드의 개수는 2개로 고정되어 있었다. 요구사항이 변경돼 사용자는 입력 필드를 동적으로 추가하거나 삭제할 수 있게 했다. 변경된 요구사항을 반영하기 위해 JPA와 RDB의 설계를 수정했다. 우선, RDB에서는 간단하게 동적 필드를 테이블로 분리했다. 분리한 테이블은 고유ID를 갖고 게시글의 ID를 FK로 갖는다. 다음으로 JPA 수정에 들어 갔다. 게시글과 이력의 관계는 1:N관계 즉, 한 게시글은 N개의 이력을 갖는다. JPA에서 1:N관계를 설계할 때 고려해야할 2가지 사항이 있다. 첫째는 연관관계를 단방향으로 가질지 양방향으로 가질지를 결정해야 한다. 대부분의 객체는 단방향으로 ..