Files
llm-wiki/raw/company-tech-blogs/read-only-tx-hibernate-optimization-vladmihalcea.md
T

8.5 KiB

title, source_type, url, archive_url, related_branches, related_projects, tags, created, last_reviewed
title source_type url archive_url related_branches related_projects tags created last_reviewed
company-tech-blog / Spring read-only transaction Hibernate optimization — Vlad Mihalcea company-tech-blog https://vladmihalcea.com/spring-read-only-transaction-hibernate-optimization/
feature-application-query-bypass-contract
ca-skeleton
spring
hibernate
read-only
transaction
dirty-check
flush-mode
performance
memory
ca-skeleton
2026-06-04 2026-06-04

Spring read-only transaction Hibernate optimization — Vlad Mihalcea

Layer: raw/company-tech-blogs/ — Vlad Mihalcea 의 기술 블로그 (vladmihalcea.com) 포스트 "Spring read-only transaction Hibernate optimization" (2018-09-25) 발췌. Hibernate 작동 전문가인 저자가 Spring 5.1 에서 개선된 @Transactional(readOnly=true) 의 Hibernate 세션 최적화를 설명.

출처 신뢰도: engineering-blog 등급 — Vlad Mihalcea 는 Hibernate core committer 이자 "High-Performance Java Persistence" 저자. 개인 블로그이나 Hibernate 공식 contributor 의 기술 분석. Spring 공식 문서가 아님. company-case-study 승급 불가 (사례 아닌 기술 분석).

Parent / 활용 branch (필수)

Branch 이 자료가 정당화하는 결정
raw/branch-notes/feature-application-query-bypass-contract D2 (transaction bypass — read-only transaction 을 쓰지 않을 때의 실제 cost) 의 기술적 근거 — readOnly=true 가 Hibernate session setDefaultReadOnly(true) 로 propagate 되어 loaded state (hydrated state) 를 discarded 하는 최적화의 실제 의미. 단순 single-entity SELECT 에는 dirty-check overhead 가 미미함을 시사.

출처 / Source

왜 저장했는지 / Why archived

ca-tmpl 의 transaction bypass 결정(D2)에서 "no-tx read 가 얼마나 위험한가" 의 반대 근거로 보관. readOnly=true 의 실제 최적화 내용이 메모리 절약과 dirty-check skip 이며, 단순 단일 SELECT 에는 이 최적화의 이득이 미미함을 시사. 결과적으로 skeleton 의 no-tx read 허용 범위를 정당화하는 보조 근거.

핵심 인용 / Key quotes (verbatim)

"Prior to Spring 5.1, when using Hibernate, the readOnly attribute of the @Transactional annotation was only setting the current Session flush mode to FlushType.MANUAL, therefore disabling the automatic dirty checking mechanism."

"the readOnly attribute did not propagate to the underlying Hibernate Session, I decided to create the SPR-16956 issue and provided a Pull Request...which after being Jürgenized, it got integrated"

"upon loading an entity, the loaded state is stored by the Hibernate Session unless the entity is loaded in read-only mode."

"the main advantage of the Spring 5.1 read-only optimization for Hibernate is that we can save a lot of memory when loading read-only entities since the loaded state is discarded right away"

"if the user tries to do a manual flush, entities that are virtually read-only won't be propagated"

Claims Extracted / 추출된 주장

Claim ID Claim (이 자료가 직접 말하는 것) Evidence quote Strength Applies to Does not prove
VM-READTX-C1 Spring 5.1 이전에는 @Transactional(readOnly=true) 가 Hibernate Session flush mode 를 FlushType.MANUAL 로만 설정하고, underlying Hibernate Session 에 propagate 되지 않았다 "Prior to Spring 5.1...the readOnly attribute...was only setting the current Session flush mode to FlushType.MANUAL, therefore disabling the automatic dirty checking mechanism." engineering-blog Spring 5.1 미만 + Hibernate 사용 환경 Spring 5.1+ 이후에도 flush mode 설정이 일어나지 않는다는 뜻은 아님 — 5.1+ 에서는 추가로 setDefaultReadOnly(true) 도 호출됨
VM-READTX-C2 Spring 5.1+ 에서는 @Transactional(readOnly=true) 가 underlying Hibernate Session 에 setDefaultReadOnly(true) 로 propagate 되어, 로드된 entity 의 hydrated state (loaded state snapshot) 이 즉시 discard "the readOnly attribute did not propagate to the underlying Hibernate Session" (결함 진술) + "upon loading an entity, the loaded state is stored by the Hibernate Session unless the entity is loaded in read-only mode." engineering-blog Spring 5.1+ + Hibernate JPA provider 사용 환경 (HibernateJpaDialect 경유) EclipseLink 등 다른 JPA provider 에도 동일 최적화가 적용된다는 보장 없음. Spring 5.1+ 에서도 HibernateJpaDialect 를 사용해야 적용됨
VM-READTX-C3 @Transactional(readOnly=true)주요 이득은 메모리 절약 — read-only entity 로드 시 loaded state 가 즉시 discarded 되어 persistence context 존속 기간 동안 보관되지 않음 "the main advantage of the Spring 5.1 read-only optimization for Hibernate is that we can save a lot of memory when loading read-only entities since the loaded state is discarded right away" engineering-blog 많은 entity 를 로드하는 read-heavy operation 단순 단일 entity 또는 단일 DTO projection SELECT 에 동일한 이득이 있다는 뜻은 아님 — 로드되는 entity 수가 많을수록 이득이 커짐
VM-READTX-C4 read-only entity 로 로드된 경우 manual flush 를 호출해도 해당 entity 는 propagate 되지 않음 — dirty check 자체가 skip 됨 "if the user tries to do a manual flush, entities that are virtually read-only won't be propagated" engineering-blog Hibernate Session 의 flush 가 read-only entity 에 미치는 영향 read-only entity 를 변경하면 예외가 발생한다는 강제 보증은 본 인용에 없음 — 변경 자체는 가능하나 flush 시 반영 안 됨

Usage Boundaries / 적용 경계

  • 이 자료가 직접 증명하는 것:
    • VM-READTX-C1: Spring 5.1 이전 readOnly=true 의 제한된 동작 (flush mode MANUAL 만)
    • VM-READTX-C2: Spring 5.1+ 에서 HibernateJpaDialect 경유 시 setDefaultReadOnly(true) 전파
    • VM-READTX-C3: 주요 이득 = 메모리 절약 (많은 entity 로드 시). query 속도 개선이 아님
    • VM-READTX-C4: dirty check skip 으로 flush 시 read-only entity 는 DB 반영 안 됨
  • 이 자료가 증명하지 않는 것:
    • 단순 단일 entity SELECT 에서 readOnly=true 유무의 실제 성능 차이 — 본 포스트의 예시는 여러 entity 를 findAllByTitle 로 bulk 로드하는 시나리오
    • readOnly=true 없이 실행(no-tx or REQUIRED write tx)하는 simple SELECT 가 응용 결과에 영향을 주는 케이스 (dirty entity 가 없으면 flush 로 인한 추가 DML 없음)
    • OSIV(open-in-view) enabled 환경에서의 동작 차이
    • DB connection 유지 시간의 차이 (transaction 경계 = connection 점유 기간 이지만 본 포스트는 이 cost 를 다루지 않음)
  • 내 프로젝트에 적용하려면 추가 확인이 필요한 것:
    • ca-tmpl 에서 TransactionPort.inRead 없이 실행되는 repository read method 가 HikariCP autocommit=true 환경에서 개별 connection 을 점유하는지 측정
    • Hibernate 6 (Spring Boot 3.x) 에서 setDefaultReadOnly(true) 가 실제로 loaded state 를 즉시 discard 하는지 통합 테스트 검증

메모 / Notes

  • 중요 해석: VM-READTX-C3 가 명시하듯 readOnly=true 의 주요 이득은 메모리 절약이지 query latency 개선이 아님. 단순 ID-by-PK lookup 같은 single-entity read 에서는 hydrated state 가 1개이므로 메모리 이득이 미미. 따라서 ca-tmpl 의 no-tx bypass 가 허용되는 "단순 읽기" 정의에는 VM-READTX-C3 의 scope — 많은 entity 를 bulk 로드하는 연산은 readOnly=true 가 의미 있음.
  • 본 포스트는 Hibernate core committer 의 기술 분석이므로 engineering-blog 등급이나 Hibernate 내부 동작 설명의 신뢰도는 높음. 단 production case study 가 아니므로 company-case-study 로 승급 불가.