SlideShare a Scribd company logo
1 of 31
Hibernate 초급을 넘어서
박성재
bluehatch@gmail.com
하이버네이트 요소
• 클래스 맵핑
• 연관 관계 맵핑
• 영속성 컨텍스트
• 트랜잭션
• Fetch와 2nd Cache
• HQL, Criteria
오늘은 이것만
• 클래스 맵핑
• 연관 관계 맵핑
• 영속성 컨텍스트
• 트랜잭션
• Fetch와 2nd Cache
• HQL, Criteria
영속성 생명 주기
영속성 생명 주기 – 조금 더 단순하게…
비영속 객
체
(Transient)
영속 객체
(Persistent)
준영속 객
체
(Detached)
get(), load()
, any query
영속성 생명 주기 – 객체 상태
• 비영속 객체(Transient)
– new 연산자로 생성된 객체
– DB나 영속성 컨텍스트와 연관이 없다.
• 영속 객체(Persistent)
– DB와 동일성을 지닌 엔터티(PK 기준)
– 플러시 시점에 DB에 동기화(변경 내용 자동 반영)
• 준영속 객체(Detached)
– 작업 단위가 완료되어 영속성 컨텍스트(세션)가 닫힘
– 재진입, 병합을 통해 영속 상태로 진입
• 삭제 객체(Removed)
– DB에서 삭제됨
영속성 컨텍스트(aka 세션)
Database
영속성 컨텍스트 특징
• 영속 객체 자동 변경 감지
• 1차 캐시
• 객체 동일성 보장(== 비교)
• 트랜잭션을 지원하는 지연 쓰기
• 지연 로딩
• 일반적으로 쓰래드 단위
영속성 컨텍스트 – 자동 변경 감지
• 영속 객체의 현재 스냅샷과 이전 스냅샷을 비교
• 플러시 시점에 변경된 객체를 찾아 자동 업데이
트 수행
• 동적 업데이트 설정을 (dynamicUpdate = true)
통해 변경된 컬럼만 업데이트 가능
영속성 컨텍스트 – 1차 캐시
• PK로 객체 조회시 영속성 컨텍스트에서 찾아
반환
– 컨텍스트에 존재 안 할 경우만 DB 쿼리 수행
– get(), load()
• 일반적인 쿼리를 수행 한 경우에도 쿼리 결과
집합은 영속성 컨텍스트와 상호 작용함
– 예) A가 이미 컨텍스트에 있는 상태에서 쿼리 결과
가 A, B, C이면 A는 컨텍스트에 이미 있는 것으로
대체 하여 결과 집합 반환.
– 값만 조회하는 스칼라 쿼리 제외
영속성 컨텍스트 – 1차 캐시
영속성 컨텍스트 – 지연 쓰기/지연 로딩
• 하이버네이트는 DB 요청을 최대한 뒤로 미룬다.
– 변경 사항을 모아 DB 요청을 최소화
– DB lock을 최대한 짧게 유지
• 지연 로딩을 통해 성능 향상
– 세션 내에서만 유효(LazyInitializationException)
• update()는 준영속 객체를 컨텍스트에 재진입하는
용도이다.
– 사실 reattach() 라는 이름이 더 적합
– 세션 내에서 명시적 호출이 있더라도 플러시 시점에 동작
함
영속성 컨텍스트 – 플러시
• 영속성 컨텍스트의 변경 내용을 DB와 동기화
– 컨텍스트 비우는거 아님~!
• 플러시 모드 : AUTO, COMMIT, MANUAL, NEVER
• AUTO 모드
– Hibernate 기본 모드
– 플러시 동작 시점: 트랜잭션 커밋, 명시적인 Session.flush(), 쿼리 실행 전
• MANUAL 모드
– 트랜잭션 내에서 DB 쿼리가 많으며 컨텍스트에 대량의 인스턴스가 로딩되는 작업인
경우 MANUAL 모드 사용하자~
영속성 컨텍스트 – Open Session In View 패턴
• 영속성 컨텍스트(세션)를 View까지 열어둠
• View에서 지연 로딩이 가능해짐
• OSIV vs FACADE vs DTO
– OSIV를 사용하지 않으면 준영속 상태가 되기 전에 프락시
(지연 로딩 객체)를 초기화 해야 함
• 스프링 OSIV는 엔터티 수정을 트랜잭션이 동작하는
계층에서만 지원
– 초기 플러시 모드: FlushMode.MANUAL
– 각 트랜잰셕 시작시 FlushMode.AUTO로 변경되며 각 트랜
잭션이 종료되면 다시 FlushMode.MANUAL로 원복
트랜잭션 범위
영속성 컨텍스트 – 스프링 OSIV
Filter
Interceptor
Controller
View
Service DAO
영속성 컨텍스트(세션) 생존 범위
FlushMode.MANUAL FlushMode.AUTO
트랜잭션 – ACID
• 원자성(Atomic)
– 트랜잭션 내의 여러 작업은 모두 성공 혹은 모두 실패
• 일관성(Consistency)
– 예)무결정 제약 조건
• 격리성(Isolation)
– 동시에 실행하는 트랜잭션들이 서로에게 영향을 미치지 않
도록 격리되어야 함
• 지속성(Durability)
– 트랜잭션이 성공적으로 끝나면 결과는 기록되어야 함
트랜잭션 – 격리 수준
격리 수준 DIRTY READ NON-REPATABLE
READ
PHANTOM READ
커밋되지 않은 읽
기
O O O
커밋된 읽기 O O
반복 가능한 읽기 O
직렬화
• DIRTY READ: 커밋되지 않고 수정 중인 데이터를 읽는 문제
• NON-REPATABLE READ: 한 트랜잭션 내에서 같은 쿼리를 두 번 수행할 때 그 사이에 다
른 트랜잭션이 값을 수정 또는 삭제함으로써 두 쿼리의 결과가 상이하게 나타나는 비 일관
성 발생
• PHANTOM READ: 한 트랜잭션 안에서 일정 범위의 레코드를 두 번 이상 읽을 때, 첫 번째
쿼리에서 없던 레코드가 두 번째 쿼리에서 나타나는 현상. 이는 트랜잭션 도중 새로운 레코
드가 삽입되는 것을 허용하기 때문에 나타남.
트랜잭션 – 격리 수준(하이버네이트 적용)
격리 수준 DIRTY READ NON-REPATABLE
READ
PHANTOM READ
커밋되지 않은 읽
기
O O O
커밋된 읽기(일반
적인 수준)
영속성 컨텍스트+
버전 관리로 해결
O
반복 가능한 읽기 O
직렬화
• DIRTY READ: 커밋되지 않고 수정 중인 데이터를 읽는 문제
• NON-REPATABLE READ: 한 트랜잭션 내에서 같은 쿼리를 두 번 수행할 때 그 사이에 다
른 트랜잭션이 값을 수정 또는 삭제함으로써 두 쿼리의 결과가 상이하게 나타나는 비 일관
성 발생
• PHANTOM READ: 한 트랜잭션 안에서 일정 범위의 레코드를 두 번 이상 읽을 때, 첫 번째
쿼리에서 없던 레코드가 두 번째 쿼리에서 나타나는 현상. 이는 트랜잭션 도중 새로운 레코
드가 삽입되는 것을 허용하기 때문에 나타남.
트랜잭션 - 낙관적 락, 비관적 락
• 낙관적 락
– 어플리케이션(하이버네이트)에서 제공하는 락
– @Version -> 최초 커밋만 인정하기 두 번째부터 예외
를 던짐
• 비관적 락
– Database lock을 사용
– select for update
트랜잭션 – 경계 설정
• 프로그래밍 방식
– 스프링 TransactionTemplate 사용
– 정교하게 경계를 나눌 때 사용
• 선언적
– @Transactional(메소드 단위)
– AOP
– 일반적인 방법
트랜잭션 – 예외처리하기
• @Transactional 메소드 외부로 예외가 던져지면
롤백 수행
• 메소드 콜 트리에서 중첩된 @Transactional 중
예외가 밖으로 던져질 경우에도 롤백 수행
• 트랜잭션 롤백 예외
– rollbackFor, rollbackForClassName
– noRollbackFor, noRollbackForClassName
트랜잭션 – 스프링에서 제공하는 트랜잭션 전파
속성
• REQUIRED
– 기본 속성이며 대부분
이 속성이면 충분함
– 이미 시작된 트랜잭션
이 있으면 참여하고 없
으면 새로 시작
• REQUIRES_NEW
– 항상 새로운 트랜잭션
을 시작
– 이미 진행 중인 트랜잭
션이 있으면 잠시 보류
시킴
– 사용 예) 권한 체크, 감
사 로깅
• SUPPORTS, MANDATORY, NOT_SUPPORTED, NEVER, NESTED
N+1 문제
member
-id
-name
…
orders
-id
-member_id
…
1 *
-- get all of the member first
select * from member
-- get the orders for each member returned
select * from orders where member_id = 1
select * from orders where member_id = 2
select * from orders where member_id = 3
select * from orders where member_id = …
select * from orders where member_id = N
페치 전략
• Select 페치
– 연관된 인스턴스나 콜렉션을 하나씩 SELECT 실행
• Join 페치
– SELECT 절에서 OUTER JOIN으로 한번에 쿼리
– 중복 제거를 위해 distinct 필요
• Subselect 페치
– 이전 쿼리 조건을 sub query조건에 추가하여 SELECT 실행
– 맵핑시 결정: @Fetch(FetchMode.SUBSELECT)
• Batch 페치
– select fetching의 최적화 전략
– PK또는 FK 목록을 통해 하나의 SELECT절로 묶어서 쿼리
– 맵핑시 결정: @BatchSize(size=10)
N+1 문제 – 조인을 이용한 즉시 페치
-- HQL
select distinct m from Member m join fetch m.orders
-- 실행된 SQL
SELECT DISTINCT M.*, O.* FROM MEMBER M INNJER
JOIN ORDERS O ON M.ID = O.MEMBER_ID
-> distinct 옵션 적용 시 하이버네이트는 SQL에 DISTINCT
적용과 함께 결과 리스트에세 Member객체를 중복 제거
함
-> 컬렉션을 두 개 이상 조인 페치할 경우 카테시안 곱
(Cartesian Product) 발생함
N+1 문제 – Subselect 페치
-- HQL
select m from Member m where m.id > 10
-- 지연 로딩된 엔터티를 사용하는 시점의 SQL 실행문
SELECT O.* FROM ORDERS O
WHERE O.MEMBER_ID IN (
SELECT M.ID
FROM MEMBER M
WHERE M.ID > 10
)
N+1 문제 – Batch로 데이터 선행 페치
-- HQL
select m from Member …
-- 지연 로딩된 엔터티를 사용하는 시점의 SQL 실행문
(BatchSize개수 만큼 로딩하는 쿼리를 여러 번 수행)
SELECT O.* FROM ORDERS O
WHERE O.MEMBER_ID IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
하이버네이트의 영속성 컨텍스트와 패치 전략

More Related Content

What's hot

스레드
스레드스레드
스레드
xxbdxx
 

What's hot (20)

Osx cocoa study-ch36_nstask
Osx cocoa study-ch36_nstaskOsx cocoa study-ch36_nstask
Osx cocoa study-ch36_nstask
 
[D2 CAMPUS] 안드로이드 오픈소스 스터디자료 - Http Request
[D2 CAMPUS] 안드로이드 오픈소스 스터디자료 - Http Request[D2 CAMPUS] 안드로이드 오픈소스 스터디자료 - Http Request
[D2 CAMPUS] 안드로이드 오픈소스 스터디자료 - Http Request
 
[2015-06-05] Oracle TX Lock
[2015-06-05] Oracle TX Lock[2015-06-05] Oracle TX Lock
[2015-06-05] Oracle TX Lock
 
10장
10장10장
10장
 
Effective Java ~
Effective Java ~Effective Java ~
Effective Java ~
 
windows via c++ Ch 5. Job
windows via c++ Ch 5. Jobwindows via c++ Ch 5. Job
windows via c++ Ch 5. Job
 
Scope and Closure of JavaScript
Scope and Closure of JavaScript Scope and Closure of JavaScript
Scope and Closure of JavaScript
 
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
 
MySQL 상태 메시지 분석 및 활용
MySQL 상태 메시지 분석 및 활용MySQL 상태 메시지 분석 및 활용
MySQL 상태 메시지 분석 및 활용
 
Pg day seoul 2016 session_02_v1.0_ff
Pg day seoul 2016 session_02_v1.0_ffPg day seoul 2016 session_02_v1.0_ff
Pg day seoul 2016 session_02_v1.0_ff
 
스레드
스레드스레드
스레드
 
Android Network
Android NetworkAndroid Network
Android Network
 
Solr 디렉토리 구조와 관리 콘솔
Solr 디렉토리 구조와 관리 콘솔Solr 디렉토리 구조와 관리 콘솔
Solr 디렉토리 구조와 관리 콘솔
 
Pg report 20161010_02
Pg report 20161010_02Pg report 20161010_02
Pg report 20161010_02
 
Free rtos seminar
Free rtos seminarFree rtos seminar
Free rtos seminar
 
Javascript closure 2차과제 이승찬
Javascript closure 2차과제 이승찬Javascript closure 2차과제 이승찬
Javascript closure 2차과제 이승찬
 
Mongodb 관리
Mongodb 관리Mongodb 관리
Mongodb 관리
 
[143] Modern C++ 무조건 써야 해?
[143] Modern C++ 무조건 써야 해?[143] Modern C++ 무조건 써야 해?
[143] Modern C++ 무조건 써야 해?
 
Pgday bdr 천정대
Pgday bdr 천정대Pgday bdr 천정대
Pgday bdr 천정대
 
Windows via C/C++ 06 스레드의 기본
Windows via C/C++ 06 스레드의 기본Windows via C/C++ 06 스레드의 기본
Windows via C/C++ 06 스레드의 기본
 

Similar to 하이버네이트의 영속성 컨텍스트와 패치 전략

[2015 07-06-윤석준] Oracle 성능 최적화 및 품질 고도화 4
[2015 07-06-윤석준] Oracle 성능 최적화 및 품질 고도화 4[2015 07-06-윤석준] Oracle 성능 최적화 및 품질 고도화 4
[2015 07-06-윤석준] Oracle 성능 최적화 및 품질 고도화 4
Seok-joon Yun
 

Similar to 하이버네이트의 영속성 컨텍스트와 패치 전략 (20)

Tajo and SQL-on-Hadoop in Tech Planet 2013
Tajo and SQL-on-Hadoop in Tech Planet 2013Tajo and SQL-on-Hadoop in Tech Planet 2013
Tajo and SQL-on-Hadoop in Tech Planet 2013
 
REST with Spring
REST with SpringREST with Spring
REST with Spring
 
[Solr 스터디] Solr 설정 및 색인 (2017)
[Solr 스터디] Solr 설정 및 색인 (2017)[Solr 스터디] Solr 설정 및 색인 (2017)
[Solr 스터디] Solr 설정 및 색인 (2017)
 
Ksug2015 - JPA3, JPA 내부구조
Ksug2015 - JPA3, JPA 내부구조Ksug2015 - JPA3, JPA 내부구조
Ksug2015 - JPA3, JPA 내부구조
 
Hadoop distributed file system rev3
Hadoop distributed file system rev3Hadoop distributed file system rev3
Hadoop distributed file system rev3
 
[2015 07-06-윤석준] Oracle 성능 최적화 및 품질 고도화 4
[2015 07-06-윤석준] Oracle 성능 최적화 및 품질 고도화 4[2015 07-06-윤석준] Oracle 성능 최적화 및 품질 고도화 4
[2015 07-06-윤석준] Oracle 성능 최적화 및 품질 고도화 4
 
if kakao dev 2019_Ground X_Session 04
if kakao dev 2019_Ground X_Session 04if kakao dev 2019_Ground X_Session 04
if kakao dev 2019_Ground X_Session 04
 
Git
Git Git
Git
 
OracleHistory2
OracleHistory2OracleHistory2
OracleHistory2
 
elasticsearch_적용 및 활용_정리
elasticsearch_적용 및 활용_정리elasticsearch_적용 및 활용_정리
elasticsearch_적용 및 활용_정리
 
자바 웹 개발 시작하기 (6주차 : 커뮤니티를 만들어보자!)
자바 웹 개발 시작하기 (6주차 : 커뮤니티를 만들어보자!)자바 웹 개발 시작하기 (6주차 : 커뮤니티를 만들어보자!)
자바 웹 개발 시작하기 (6주차 : 커뮤니티를 만들어보자!)
 
실무로 배우는 시스템 성능 최적화 - 4부. 프로세스 이해하기
실무로 배우는 시스템 성능 최적화 - 4부. 프로세스 이해하기실무로 배우는 시스템 성능 최적화 - 4부. 프로세스 이해하기
실무로 배우는 시스템 성능 최적화 - 4부. 프로세스 이해하기
 
Linux programming study
Linux programming studyLinux programming study
Linux programming study
 
InfiniFlux vs RDBMS
InfiniFlux vs RDBMSInfiniFlux vs RDBMS
InfiniFlux vs RDBMS
 
Presto User & Admin Guide
Presto User & Admin GuidePresto User & Admin Guide
Presto User & Admin Guide
 
Kubernetes
Kubernetes Kubernetes
Kubernetes
 
Git: A Motivating Introduction
Git: A Motivating IntroductionGit: A Motivating Introduction
Git: A Motivating Introduction
 
[pgday.Seoul 2022] PostgreSQL구조 - 윤성재
[pgday.Seoul 2022] PostgreSQL구조 - 윤성재[pgday.Seoul 2022] PostgreSQL구조 - 윤성재
[pgday.Seoul 2022] PostgreSQL구조 - 윤성재
 
Hadoop Introduction (1.0)
Hadoop Introduction (1.0)Hadoop Introduction (1.0)
Hadoop Introduction (1.0)
 
About git
About gitAbout git
About git
 

하이버네이트의 영속성 컨텍스트와 패치 전략

  • 2. 하이버네이트 요소 • 클래스 맵핑 • 연관 관계 맵핑 • 영속성 컨텍스트 • 트랜잭션 • Fetch와 2nd Cache • HQL, Criteria
  • 3. 오늘은 이것만 • 클래스 맵핑 • 연관 관계 맵핑 • 영속성 컨텍스트 • 트랜잭션 • Fetch와 2nd Cache • HQL, Criteria
  • 4.
  • 6. 영속성 생명 주기 – 조금 더 단순하게… 비영속 객 체 (Transient) 영속 객체 (Persistent) 준영속 객 체 (Detached) get(), load() , any query
  • 7. 영속성 생명 주기 – 객체 상태 • 비영속 객체(Transient) – new 연산자로 생성된 객체 – DB나 영속성 컨텍스트와 연관이 없다. • 영속 객체(Persistent) – DB와 동일성을 지닌 엔터티(PK 기준) – 플러시 시점에 DB에 동기화(변경 내용 자동 반영) • 준영속 객체(Detached) – 작업 단위가 완료되어 영속성 컨텍스트(세션)가 닫힘 – 재진입, 병합을 통해 영속 상태로 진입 • 삭제 객체(Removed) – DB에서 삭제됨
  • 9. 영속성 컨텍스트 특징 • 영속 객체 자동 변경 감지 • 1차 캐시 • 객체 동일성 보장(== 비교) • 트랜잭션을 지원하는 지연 쓰기 • 지연 로딩 • 일반적으로 쓰래드 단위
  • 10. 영속성 컨텍스트 – 자동 변경 감지 • 영속 객체의 현재 스냅샷과 이전 스냅샷을 비교 • 플러시 시점에 변경된 객체를 찾아 자동 업데이 트 수행 • 동적 업데이트 설정을 (dynamicUpdate = true) 통해 변경된 컬럼만 업데이트 가능
  • 11. 영속성 컨텍스트 – 1차 캐시 • PK로 객체 조회시 영속성 컨텍스트에서 찾아 반환 – 컨텍스트에 존재 안 할 경우만 DB 쿼리 수행 – get(), load() • 일반적인 쿼리를 수행 한 경우에도 쿼리 결과 집합은 영속성 컨텍스트와 상호 작용함 – 예) A가 이미 컨텍스트에 있는 상태에서 쿼리 결과 가 A, B, C이면 A는 컨텍스트에 이미 있는 것으로 대체 하여 결과 집합 반환. – 값만 조회하는 스칼라 쿼리 제외
  • 13. 영속성 컨텍스트 – 지연 쓰기/지연 로딩 • 하이버네이트는 DB 요청을 최대한 뒤로 미룬다. – 변경 사항을 모아 DB 요청을 최소화 – DB lock을 최대한 짧게 유지 • 지연 로딩을 통해 성능 향상 – 세션 내에서만 유효(LazyInitializationException) • update()는 준영속 객체를 컨텍스트에 재진입하는 용도이다. – 사실 reattach() 라는 이름이 더 적합 – 세션 내에서 명시적 호출이 있더라도 플러시 시점에 동작 함
  • 14. 영속성 컨텍스트 – 플러시 • 영속성 컨텍스트의 변경 내용을 DB와 동기화 – 컨텍스트 비우는거 아님~! • 플러시 모드 : AUTO, COMMIT, MANUAL, NEVER • AUTO 모드 – Hibernate 기본 모드 – 플러시 동작 시점: 트랜잭션 커밋, 명시적인 Session.flush(), 쿼리 실행 전 • MANUAL 모드 – 트랜잭션 내에서 DB 쿼리가 많으며 컨텍스트에 대량의 인스턴스가 로딩되는 작업인 경우 MANUAL 모드 사용하자~
  • 15. 영속성 컨텍스트 – Open Session In View 패턴 • 영속성 컨텍스트(세션)를 View까지 열어둠 • View에서 지연 로딩이 가능해짐 • OSIV vs FACADE vs DTO – OSIV를 사용하지 않으면 준영속 상태가 되기 전에 프락시 (지연 로딩 객체)를 초기화 해야 함 • 스프링 OSIV는 엔터티 수정을 트랜잭션이 동작하는 계층에서만 지원 – 초기 플러시 모드: FlushMode.MANUAL – 각 트랜잰셕 시작시 FlushMode.AUTO로 변경되며 각 트랜 잭션이 종료되면 다시 FlushMode.MANUAL로 원복
  • 16. 트랜잭션 범위 영속성 컨텍스트 – 스프링 OSIV Filter Interceptor Controller View Service DAO 영속성 컨텍스트(세션) 생존 범위 FlushMode.MANUAL FlushMode.AUTO
  • 17.
  • 18. 트랜잭션 – ACID • 원자성(Atomic) – 트랜잭션 내의 여러 작업은 모두 성공 혹은 모두 실패 • 일관성(Consistency) – 예)무결정 제약 조건 • 격리성(Isolation) – 동시에 실행하는 트랜잭션들이 서로에게 영향을 미치지 않 도록 격리되어야 함 • 지속성(Durability) – 트랜잭션이 성공적으로 끝나면 결과는 기록되어야 함
  • 19. 트랜잭션 – 격리 수준 격리 수준 DIRTY READ NON-REPATABLE READ PHANTOM READ 커밋되지 않은 읽 기 O O O 커밋된 읽기 O O 반복 가능한 읽기 O 직렬화 • DIRTY READ: 커밋되지 않고 수정 중인 데이터를 읽는 문제 • NON-REPATABLE READ: 한 트랜잭션 내에서 같은 쿼리를 두 번 수행할 때 그 사이에 다 른 트랜잭션이 값을 수정 또는 삭제함으로써 두 쿼리의 결과가 상이하게 나타나는 비 일관 성 발생 • PHANTOM READ: 한 트랜잭션 안에서 일정 범위의 레코드를 두 번 이상 읽을 때, 첫 번째 쿼리에서 없던 레코드가 두 번째 쿼리에서 나타나는 현상. 이는 트랜잭션 도중 새로운 레코 드가 삽입되는 것을 허용하기 때문에 나타남.
  • 20. 트랜잭션 – 격리 수준(하이버네이트 적용) 격리 수준 DIRTY READ NON-REPATABLE READ PHANTOM READ 커밋되지 않은 읽 기 O O O 커밋된 읽기(일반 적인 수준) 영속성 컨텍스트+ 버전 관리로 해결 O 반복 가능한 읽기 O 직렬화 • DIRTY READ: 커밋되지 않고 수정 중인 데이터를 읽는 문제 • NON-REPATABLE READ: 한 트랜잭션 내에서 같은 쿼리를 두 번 수행할 때 그 사이에 다 른 트랜잭션이 값을 수정 또는 삭제함으로써 두 쿼리의 결과가 상이하게 나타나는 비 일관 성 발생 • PHANTOM READ: 한 트랜잭션 안에서 일정 범위의 레코드를 두 번 이상 읽을 때, 첫 번째 쿼리에서 없던 레코드가 두 번째 쿼리에서 나타나는 현상. 이는 트랜잭션 도중 새로운 레코 드가 삽입되는 것을 허용하기 때문에 나타남.
  • 21. 트랜잭션 - 낙관적 락, 비관적 락 • 낙관적 락 – 어플리케이션(하이버네이트)에서 제공하는 락 – @Version -> 최초 커밋만 인정하기 두 번째부터 예외 를 던짐 • 비관적 락 – Database lock을 사용 – select for update
  • 22. 트랜잭션 – 경계 설정 • 프로그래밍 방식 – 스프링 TransactionTemplate 사용 – 정교하게 경계를 나눌 때 사용 • 선언적 – @Transactional(메소드 단위) – AOP – 일반적인 방법
  • 23. 트랜잭션 – 예외처리하기 • @Transactional 메소드 외부로 예외가 던져지면 롤백 수행 • 메소드 콜 트리에서 중첩된 @Transactional 중 예외가 밖으로 던져질 경우에도 롤백 수행 • 트랜잭션 롤백 예외 – rollbackFor, rollbackForClassName – noRollbackFor, noRollbackForClassName
  • 24. 트랜잭션 – 스프링에서 제공하는 트랜잭션 전파 속성 • REQUIRED – 기본 속성이며 대부분 이 속성이면 충분함 – 이미 시작된 트랜잭션 이 있으면 참여하고 없 으면 새로 시작 • REQUIRES_NEW – 항상 새로운 트랜잭션 을 시작 – 이미 진행 중인 트랜잭 션이 있으면 잠시 보류 시킴 – 사용 예) 권한 체크, 감 사 로깅 • SUPPORTS, MANDATORY, NOT_SUPPORTED, NEVER, NESTED
  • 25.
  • 26. N+1 문제 member -id -name … orders -id -member_id … 1 * -- get all of the member first select * from member -- get the orders for each member returned select * from orders where member_id = 1 select * from orders where member_id = 2 select * from orders where member_id = 3 select * from orders where member_id = … select * from orders where member_id = N
  • 27. 페치 전략 • Select 페치 – 연관된 인스턴스나 콜렉션을 하나씩 SELECT 실행 • Join 페치 – SELECT 절에서 OUTER JOIN으로 한번에 쿼리 – 중복 제거를 위해 distinct 필요 • Subselect 페치 – 이전 쿼리 조건을 sub query조건에 추가하여 SELECT 실행 – 맵핑시 결정: @Fetch(FetchMode.SUBSELECT) • Batch 페치 – select fetching의 최적화 전략 – PK또는 FK 목록을 통해 하나의 SELECT절로 묶어서 쿼리 – 맵핑시 결정: @BatchSize(size=10)
  • 28. N+1 문제 – 조인을 이용한 즉시 페치 -- HQL select distinct m from Member m join fetch m.orders -- 실행된 SQL SELECT DISTINCT M.*, O.* FROM MEMBER M INNJER JOIN ORDERS O ON M.ID = O.MEMBER_ID -> distinct 옵션 적용 시 하이버네이트는 SQL에 DISTINCT 적용과 함께 결과 리스트에세 Member객체를 중복 제거 함 -> 컬렉션을 두 개 이상 조인 페치할 경우 카테시안 곱 (Cartesian Product) 발생함
  • 29. N+1 문제 – Subselect 페치 -- HQL select m from Member m where m.id > 10 -- 지연 로딩된 엔터티를 사용하는 시점의 SQL 실행문 SELECT O.* FROM ORDERS O WHERE O.MEMBER_ID IN ( SELECT M.ID FROM MEMBER M WHERE M.ID > 10 )
  • 30. N+1 문제 – Batch로 데이터 선행 페치 -- HQL select m from Member … -- 지연 로딩된 엔터티를 사용하는 시점의 SQL 실행문 (BatchSize개수 만큼 로딩하는 쿼리를 여러 번 수행) SELECT O.* FROM ORDERS O WHERE O.MEMBER_ID IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)