🏷 IDENTITY 전략
- mysql에서 사용
- 기본키 생성을 데이터베이스에 위임한다.
- em.persist() 로 객체를 영속화 하는 시점에 insert query 가 db에 전송되고 여기서 반환되는 식별자 값을 가지고 1차 캐시에 저장한다.
❓em.persist() 에 대해서 좀 더 알아보자
보통 객체 생성 후, em.persist(Person) 을 사용하게 되면, 영속 상태 즉, 1차 캐시에 저장되게 된다.
이후, commit() 을 하기 전까지는, 쓰기 지연 sql 저장소에 보관되어 있다가,
commit() 이 되면, 엔티티 매니저는 영속성 컨텍스트를 flush() 하게 된다.
✔️ 영속성 컨텍스트의 flush()
- 영속성 컨텍스트의 변경 내용을 데이터베이스에 동기화 하는 작업으로, 이때 등록, 수정, 삭제된 엔티티를 db에 반영하게 된다.
즉, 쓰기 지연 sql 보관소에 모인 쿼리를 데이터베이스에 보내는 것이다.
이렇게 영속성 컨텍스트의 변경 내용을 데이터베이스에 동기화 한 후, 데이터베이스 트랜잭션을 commit() 한다.
본론으로 돌아와서!
jpa는 보통의 경우, 트렌잭션이 commit 되는 시점에 쓰기 지연 저장소에 모아놓은 쿼리를 실행하기 때문에
어플리케이션과 db 사이에 네트워크를 오가는 횟수가 줄어들고 성능상에 이득을 볼 수 있다.
하지만, Identity 전략은 db에 기본키 생성을 위임하므로, jpa 입장에서는 insert sql을 날리기 전에는 도저히 값을 알 수 없으므로,
persist() 시점에 쿼리가 나가는 것이다.
영속성 컨텍스트에서 관리하려면 기본키를 반드시 알고 있어야 하기 때문이다.
🏷 SEQUENCE 전략
- H2, Oracle db 등에서 주로 사용
- DB Sequence 를 사용해 기본키를 할당하는 방식으로, DB에서 Sequence를 생성해야지 사용 할 수 있다.
- entity 생성시 @Sequencegenerator 어노테이션 사용
✔️ AllocationSize와 성능 최적화
Sequence 전략에서 사용되는 allocationSize는 기본값이 50이므로, 따로 설정하지 않으면 호출시마다 50씩 증가한다.
그 이유는 ! DB 접근 횟수를 줄이기 위함이다!
allocationSize 만큼 sequence를 증가시키고, 메모리의 그만큼 할당시킨다.
그 후, 메모리를 활용하여 jvm안에서 sequence를 할당한다.
이는!! sequence를 선점하여 다른 여러 jvm이 동시에 동작해도 기본값이 겹치지 않도록 하는 것을 의미한다.
🤔 Indentity VS sequence 차이점
위의 내용을 공부하다 보니, 위 두개의 방식의 내부적인 동작 방식 차이점에 대해 궁금한 점이 발생하였다.
identity 전략은 entity를 먼저 db에 저장한 후에, 식별자를 조회하여 entity의 식별자로 할당하는 전략이다.
sequence 전략은 em.persist() 호출 전에 db sequence를 먼저 조회하여 식별자를 entity에 할당한 후,
entity를 영속 상태로 저장하고 그 후, commit()이 이뤄지고 flush() 발생하게 되어 entity를 db에 저장하게 된다.
이렇게 나열해보니 차이점이 명확히 보이는 것 같다.
🏷 TABLE 전략
- 위 전략은 key 생성 테이블을 사용하는 전략이다.
- key 생성 전용 table을 생성하고, name / value 로 사용할 컬럼을 사용하여 DB sequence를 흉내내는 전략이다.
- @TableGenerator 어노테이션을 사용하여 entity를 맵핑한다.
- 위 방식은 sequence 전략과 내부 동작 방식이 같다.
🏷 AUTO 전략
위 전략은 DB 방언에 따라 자동으로 identity / sequence / table 전략을 선택한다.
DB의 종류도 많고, 기본키 생성 방식도 다양하기에 해당 전략은 db를 변경해도 code 수정을 하지 않아도 되는 장점과 key 생성 전략이 정해지지 않는 개발 초기 단계에 편리하게 사용할 수 있다.
하지만 DBMS가 명확히 정해져 있다면 AUTO가 아닌 정확한 전략을 명시하는게 더 좋다.
'토이 프로젝트 배우게 된 것들 & 오류 해결🐰' 카테고리의 다른 글
[ feign client ] 사용 시, 응답값 형식 오류 (0) | 2022.12.29 |
---|---|
마이크로서비스에서 서비스간 통신 방법 차이 (0) | 2022.12.21 |
hibernate db dialect 오류 (0) | 2022.11.28 |
H2 DB file is locked 발생 원인 및 해결 방법 (0) | 2022.11.28 |
final vs static final (0) | 2022.11.21 |