반응형

PersistenceContext 12

[Spring JPA 공식 문서 기반] 20. findById()는 정말 안전할까

19편에서는 Spring Data JPA의 Repository 추상화가“무엇을 편리하게 만들었고, 무엇을 보이지 않게 가려버렸는지”를 살펴봤습니다.이번 글에서는 그 추상화의 중심에 있는 메서드,findById()가“항상 안전한 조회 수단인지”를 Spring JPA 공식 문서 기준으로 정리해보겠습니다.1. findById()에 대한 가장 흔한 오해많은 개발자가 findById()를 다음과 같이 인식합니다.“ID로 조회하니까 항상 DB에서 최신 값을 가져온다”하지만 이 인식은정확하지 않습니다.2. findById()의 실제 동작 순서Spring Data JPA의 findById()는 내부적으로EntityManager.find()를 호출합니다.그리고 이 메서드는 다음 순서로 동작합니다.Persistence C..

[Spring JPA 공식 문서 기반] 14. Lazy Loading은 왜 항상 터질까

13편에서는 즉시 로딩(EAGER)이“항상 함께 로딩한다”는 전제 때문에 실무에서 구조적인 문제를 만들 수밖에 없다는 점을 살펴봤습니다.그 다음으로 자연스럽게 나오는 말이 있습니다.“그럼 Lazy는 안전한가요?”하지만 실무에서는 오히려“Lazy는 항상 터진다”는 인식이 더 강합니다.이번 글에서는 이 인식이 왜 생겼는지, 그리고 그 오해의 정체가 무엇인지 공식 문서 관점에서 정리해보겠습니다.1. Lazy Loading은 원래 문제가 아니다먼저 분명히 해야 할 사실이 있습니다.Lazy Loading 자체는 문제 있는 기능이 아니다오히려 JPA 공식 문서 기준으로 보면, Lazy Loading은연관관계를 필요할 때만 로딩하고불필요한 JOIN을 피하며조회 성능을 제어하기 위한 기본 전략입니다.즉,Lazy는 “위..

[Spring JPA 공식 문서 기반] 11. OSIV는 왜 기본값이었고, 왜 문제였을까

10편에서는 읽기 전용 트랜잭션이“쓰기 방지 옵션”이 아니라 “조회용 Persistence Context를 올바르게 유지하기 위한 선언”이라는 점을 살펴봤습니다.이번 글에서는 그 흐름의 마지막 퍼즐 조각,OSIV(Open Session In View)가왜 기본값이었고, 왜 문제가 되었는지를 공식 문서 관점에서 정리해보겠습니다.1. OSIV는 어떤 문제를 해결하려고 등장했을까OSIV가 등장한 배경은 아주 현실적인 문제였습니다.“컨트롤러나 뷰에서 Lazy Loading이 자꾸 터진다”당시의 전형적인 구조는 이랬습니다.Service 계층에서 트랜잭션 종료Controller / View에서 엔티티 접근LazyInitializationException 발생OSIV는 이 문제를 아주 단순한 방식으로 해결합니다.“요..

[Spring JPA 공식 문서 기반] 10. 읽기 전용 트랜잭션의 진짜 의미

9편에서는 트랜잭션이 없을 때 JPA의 핵심 기능이“왜 반쪽짜리로 무너지는지”를 Persistence Context와 엔티티 상태 흐름을 통해 정리했습니다.이번 글에서는 그 다음으로 자연스럽게 따라오는 질문,“그렇다면 읽기만 하는 경우에도 왜 트랜잭션을 써야 할까?”에 답해보겠습니다.1. 읽기 전용 트랜잭션은 왜 오해를 부를까@Transactional(readOnly = true)를 보면 많은 개발자가 이렇게 이해합니다.“이 메서드는 DB에 쓰기가 안 나간다”하지만 이 이해는정확하지 않습니다.읽기 전용 트랜잭션은쓰기 자체를 금지하는 기능 ❌JPA의 동작 방식을 힌트로 알려주는 설정 ⭕입니다.2. 읽기 전용 트랜잭션의 진짜 목적Spring JPA 공식 문서 기준으로, 읽기 전용 트랜잭션의 목적은 다음 두 ..

[Spring JPA 공식 문서 기반] 9. 트랜잭션이 없으면 JPA는 왜 반쪽짜리일까

8편에서는 EntityManager가 왜 Thread-safe 하지 않은지, 그리고 그 이유가“EntityManager는 트랜잭션에 바인딩된 상태 관리자”라는 점에 있음을 정리했습니다.이번 글에서는 이 논의를 한 단계 더 밀어보겠습니다.트랜잭션이 없으면 JPA는 실제로 어떻게 동작할까?결론부터 말하면,트랜잭션이 없는 JPA는 핵심 기능의 절반이 동작하지 않습니다.그래서 우리는“JPA는 트랜잭션 기반 기술”이라고 말합니다.1. 가장 흔한 착각부터 짚자다음과 같은 코드를 보면 많은 개발자가 이렇게 기대합니다.public void updateMember() { Member m = em.find(Member.class, 1L); m.setName("newName");}겉보기에는:엔티티를 조회했고상태를..

[Spring JPA 공식 문서 기반] 8. EntityManager는 왜 Thread-safe 하지 않을까

7편에서는 영속성 컨텍스트와의 연결을 끊는 행위,detach / clear / merge가 왜 위험하고, 언제 필요한지를 살펴봤습니다.이번 글에서는 그 모든 동작의 중심에 있는 객체,EntityManager가왜 Thread-safe 하지 않은지를 Spring JPA 공식 문서 기준으로 트랜잭션 · 스레드 · 영속성 컨텍스트 관점에서 정리해보겠습니다.1. 많은 개발자가 처음 던지는 질문Spring 환경에서 우리는 보통 다음과 같은 코드를 작성합니다.@Repositorypublic class MemberRepository { @PersistenceContext private EntityManager em;}이 코드를 보면 자연스럽게 이런 의문이 듭니다.EntityManager는 싱글톤 Bean인데..

[Spring JPA 공식 문서 기반] 7. detach / clear / merge는 언제 필요한가

6편에서는 Flush가“쓰기 SQL을 DB로 전송해 일관성을 맞추는 단계”라는 점을 정리했습니다.이번 글에서는 그 Flush 이후에 등장하는,영속성 컨텍스트와의 연결을 끊는 행위즉, detach, clear, merge가 왜 위험하고, 언제 필요한지를 공식 문서 관점에서 풀어보겠습니다.이 세 가지를 이해하지 못하면,왜 데이터가 사라진 것처럼 보이는지왜 UPDATE가 두 번 나가는지왜 운영에서 재현이 어려운 버그가 생기는지를 설명할 수 없습니다.1. 영속성 컨텍스트와 “연결”의 의미먼저 전제를 다시 짚어야 합니다.엔티티가 영속 상태라는 것은,Persistence Context가 해당 객체의 상태 변화를 추적하고 있다는 의미입니다.이 연결이 유지되는 한,Dirty CheckingFlush가 자동으로 작동합니..

[Spring JPA 공식 문서 기반] 6. Flush는 왜 이렇게 예측하기 어려울까

5편에서는 JPA의 변경 감지(Dirty Checking)가“객체의 상태 변화를 SQL로 번역하는 규칙”이라는 점을 살펴봤습니다.이번 글에서는 그 다음 단계에서 가장 많은 혼란을 만드는 개념,Flush를 “쓰기 SQL과의 관계”를 중심으로 공식 문서 관점에서 정리해보겠습니다.Flush를 이해하지 못하면,왜 읽기 쿼리 전에 UPDATE가 나가는지왜 SQL은 나갔는데 롤백되는지왜 실행 시점을 코드로 예측할 수 없는지를 끝까지 설명할 수 없습니다.1. Flush를 Commit으로 이해하는 순간 문제가 시작된다Flush를 처음 접하면 대부분 이렇게 이해합니다.“Flush는 Commit 직전에 실행되는 과정이다”이 설명은절반만 맞고, 절반은 틀립니다.공식 문서 기준으로 두 개념은 명확히 구분됩니다.Flush – ..

[Spring JPA 공식 문서 기반] 5. 변경 감지(Dirty Checking)는 왜 이렇게 구현됐을까

4편에서는 Persistence Context가 단순한 캐시가 아니라,엔티티의 상태와 동일성을 지키기 위한 규칙 집합이라는 점을 살펴봤습니다.이번 글에서는 그 Persistence Context가 가장 강하게 모습을 드러내는 지점,변경 감지(Dirty Checking)를 공식 문서 관점에서 구조적으로 풀어보겠습니다.1. JPA에서 UPDATE는 왜 직접 호출하지 않을까JPA를 처음 접하면 이 점이 가장 낯설게 느껴집니다.member.setName("newName");// update 쿼리는 어디 있지?SQL을 직접 쓰던 시절이라면, 이 코드는아무 일도 하지 않은 코드처럼 보입니다.하지만 JPA에서는 이 한 줄이UPDATE SQL의 의도를 표현합니다.이게 가능한 이유가 바로 변경 감지입니다.2. 변경 감지..

[Spring JPA 공식 문서 기반] 4. Persistence Context는 캐시가 아니다

3편에서는 JPA가 왜 상태(state)를 가진 객체를 전제로 설계됐는지를 살펴봤습니다.이제 그 선택의 결과로 등장한, JPA 내부 설계의 중심 개념을 마주할 차례입니다.바로 Persistence Context입니다.Persistence Context는 JPA를 설명할 때 가장 자주 등장하지만,가장 많이 오해되는 개념이기도 합니다.1. Persistence Context를 “캐시”라고 부르는 순간 생기는 오해Persistence Context를 설명할 때 흔히 이런 표현을 씁니다.“1차 캐시 같은 거예요”이 설명은 완전히 틀린 말은 아니지만,이 표현 때문에 JPA의 핵심 목적이 가려집니다.Persistence Context의 주 목적은조회 성능 최적화 ❌DB 부하 감소 ❌가 아닙니다.공식 문서 관점에서 ..

반응형