Server/Spring JPA 26

Spring - 샤딩 모듈 개발 이야기 (feat. AbstractRoutingDataSource)

동적 데이터 소스와 스키마 이름API를 개발할 때 Java Spring으로 프로젝트를 진행하고 싶었는데 어려움이 있었다.해당 문제를 해결하고 세미나에서 발표한 내용에 대해 정리한다.모든 아키텍처나 코드는 실제 서비스와 무관하며 설명을 위해 만든 부분임을 알린다.API를 Java Spring으로 할 수 없었던 이유는 서비스의 DB구조 때문이었다.구조를 보면 DB 서버를 여러 대로 샤딩(Sharding) 하고 있고, 스키마도 분산되어 있다.데이터를 저장할 때 유저가 속한 지역별로 데이터를 특정 DB서버의 특정 스키마에 저장해서 사용한다.board_01에서 01을 파티션이라고 칭한다.특정 유저의 정보가 어떤 DB 서버의 몇 번째 파티션(스키마) 에 저장되어 있는지는 Region DB에 저장되어 있고, DB를 ..

Server/Spring JPA 2022.05.05

JPA - 비관적 락, 낙관적 락 (+ 트랜잭션 격리 수준) 정리!

격리 수준 락(Lock)을 이해하기 전에 트랜잭션 격리 수준을 먼저 알아야한다. 트랜잭션 격리수준(isolation level)이란 동시에 여러 트랜잭션을 처리할 때, 트랜잭션이 얼마나 서로 고립되어 있는지를 의미한다. 즉, 해당 트랜잭션이 다른 트랜잭션에서 변경한 데이터를 볼 수 있는 기준을 결정하는 것이다. 격리수준은 크게 4가지로 나눌 수 있다. READ UNCOMMITTED 커밋되지 않은 데이터를 읽을 수 있다. Dirty Read, Dirty Write가 발생할 수 있다. READ COMMITTED 커밋된 데이터만 읽을 수 있다. 오라클 DBMS에서 표준으로 사용하고 있고 가장 많이 선택된다. Lost Update, Write Skew, Read Skew가 발생할 수 있다. REPETABLE R..

Server/Spring JPA 2022.04.17

Spring Data JPA - JpaRepository 구현체에 @Transactional(readOnly = true)가 있는 이유

JpaRepository Spring Data JPA를 사용할 때 JpaRepository를 상속하는 interface를 만들어서 사용합니다. public interface MemberRepository extends JpaRepository { } 우리는 interface를 상속했을 뿐인데, findAll() 같은 다양한 CRUD 메서드를 사용할 수 있습니다. memberRepository.findAll(); Spring Data JPA는 내부적으로 JpaRepository를 상속하기만 해도 아래와 같은 구현체를 생성해주기 때문입니다. @Repository @Transactional(readOnly = true) public class SimpleJpaRepository implements JpaRep..

Server/Spring JPA 2022.04.10

Spring Data JPA - Bulk Update(일괄 수정)할 때 주의할 점! [영속성 컨텍스트]

Bulk Update JPA에서는 변경 감지를 통해 엔터티를 수정할 수 있지만, 그러면 각 엔터티별로 쿼리가 나가게 됩니다. 그래서 변경할 레코드들의 SET 절이 동일하다면 일괄 수정을 하는 것이 좋습니다. 가령, 만약 모든 사용자에게 10000원의 리워드를 제공하겠다고 하면 1개의 쿼리로 전체 업데이트를 할 수 있습니다. UPDATE user SET point = point + 10000; @Modifying Spring Data JPA에서는 벌크 업데이트를 위해서 Modifying 애노테이션을 사용해야 합니다. SpringDataJPA가 해당 리포지토리 메소드가 SELECT문인지 UPDATE문인지 알아야 Return Type을 결정하는데, 아직은 내부적으로 Query만 보고 판단을 못해서, 명시를 해..

Server/Spring JPA 2022.04.08

Spring Data JPA - Named query 정리 (+ @Query) !!

Spring Data JPA Named query Repository에서 SQL문을 직접 작성할 떄는 JPA의 Named query라는 것을 사용할 수 있습니다.\ Named query의 사용 방법과 장단점에 대해서 알아보겠습니다. @NamedQuery JPA에서는 NamedQuery라는 것을 제공하는데, 엔터티에 @NamedQuery 애노테이션을 사용해서 name과 query를 지정합니다. @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @NamedQuery( name = "User.findByUseranme", query = "select u from User u where u.username = :username" ) public class ..

Server/Spring JPA 2022.04.08

JPA - 영속성(persistence란) [+1차 캐시]

영속성 Spring JPA 로고를 보면 영속성(persistence)라는 단어가 크게 그려져 있습니다. 그만큼, 영속성 없이 Spring JPA를 얘기하기 힘듭니다. 영속성은 쉽게 말하면 지속을 의미합니다. 더 자세히 풀자면, 엔터티를 사용하고 바로 폐기하는 것이 아니라, 저장을 해서 지속적으로 사용하며 얻는 이점을 얻는 것을 말합니다. 예를 들어, JPA에서 repository.findOne을 동일한 데이터에 대해 조회를 5번 요청합니다. 하지만, DB의 쿼리 로그나 JPA가 기록한 로그를 보면, SELECT문이 1번만 실행됩니다. 그 이유가 영속성입니다. 첫번째 SELECT한 결과를 JPA의 1차 캐시에 보관하고 계속 재사용하기 때문입니다. 1차 캐시 JPA에서 1차 캐시는 EntityManager가..

Server/Spring JPA 2022.03.15