본문 바로가기

Spring

영속성 관리

JPA  => 설계 (: 엔티티와 테이블을 매핑) + 활용 (: 매핑한 엔티티 실제 사용)

 

활용 => 엔티티 매니저 & 영속성 컨텍스트

 

엔티티 매니저 팩토리 makes 엔티티 매니저

엔.매.팩 은 여러 스레드가 동시에 접근해도 안전 하므로 서로 다른 스레드 간에 공유 OK

엔.매 는 여러 스레드가 동시에 접근하면 동시성 문제가 발생하므로 공유 X

 

동시성 문제

동일한 하나의 데이터에 2개 이상의 스레드, 혹은 세션에서 가변 데이터를 동시에 제어할 때 나타나는 문제

하나의 세션이 데이터를 수정중일 때, 다른 세션에서 수정 전의 데이터를 조회해 로직을 처리함으로써 데이터의 정합성이 깨지는 문제

 

JPA는 데이터베이스에 접근할 때 데이터베이스 커넥션을 사용함. 그러나 JPA는 직접 커넥션 객체를 다루지 않고, EntityManager를 통해 데이터베이스와 상호작용

엔티티 매니저는 보통 트랜잭션 시작할 때 커넥션 획득, 데이터베이스 연결이 필요하지 않으면 커넥션 얻지 않음

이때 엔티티 매니저는 커넥션 객체를 통해서 데이터베이스와 상호작용을 함

 

커넥션 객체

역할

●  데이터 베이스 연결 : 실제로 데이터베이스에 연결하여 SQL 명령을 실행하고 결과 반환

●  트랜잭션 관리 : 커넥션은 트랜잭션을 관리하며, 이는 JPA의 EntityManager가 내부적으로 처리

 

문제점

DB 연결할 때마나 connection 객체를 새로 만드는 것은 비용이 많이 들고, 비효율적임

커넥션 풀

애플리케이션 로딩 시점에 Connection 객체를 미리 생성, 애플리케이션에 DB연결 필요 시 미리 준비된 Connection 객체를 사용하여 애플리케이션 성능을 향상시킴


엔티티의 생명주기

●  비영속 (new/transient) : 영속성 컨텍스트와 전혀 관계가 없는 상태

●  영속 (managed) : 영속성 컨텍스트에 저장된 상태 = 영속성 컨텍스트에 의해 관리된다

●  준영속 (detached) : 영속성 컨텍스트에 저장되었다가 분리된 상태

●  삭제 (removed) : 삭제된 상태


영속성 컨텍스트 (Persistence Context)

: 엔티티를 영구 저장하는 환경

 

엔티티 매니저 = 영속성 컨텍스트에 엔티티 보관 및 관리

    - 여러 엔티티 매니저가 같은 영속성 컨텍스트 접근 가능

    - 엔티티 매니저 생성 시 하나 만들어짐

 

persist() : 엔티티 매니저를 사용해서 회원 엔티티를 영속성 컨텍스트에 저장

 

특징

●  엔티티를 식별자 값(@Id)으로 구분  →  영속 상태는 식별자 값이 반드시 존재해야함

●  플러시를 통해 데이터베이스에 저장

 

장점

●  1차 캐시

    : 영속성 컨텍스트가 가지고 있는 내부 캐시. 영속 상태의 엔티티는 모두 이곳에 저장됨. 키는 식별자 값임

●  동일성 보장

●  트랜잭션 지원하는 쓰기 지연 (transactional write-behind)

    : 트랜잭션 커밋 전까지는 쿼리 저장소에 모아두다가 커밋 시에 모아둔 쿼리를 데이터베이스에 보냄

 

    엔티티 삭제의 경우, em.remove(data)를 호출하는 순간 data는 영속성 컨텍스트에서 제거됨!

 

    플러시

    : 영속성 컨텍스트의 변경 내용을 데이터베이스에 동기화하는 작업. 이때 등록, 수정, 삭제한 엔티티를 데이터베이스에 반영함.

      = 쓰기 지연 SQL 저장소에 모인 쿼리를 데이터베이스에 보냄

    

    ● 발생 시점

        ○ em.flush() 호출

        ○ 트랜잭션 커밋 시

        ○ JPQL 쿼리 실행 시

     ↓

      이를 변경하고 싶다면, javax.persistence.FlushModeType 사용

        ○ FlushModeType.AUTO : 커밋 & 쿼리 실행 시 (Default)

        ○ FlushModeType.COMMIT : 커밋할 때만

 

●  변경 감지 (dirty-checking)

    : 엔티티의 변경사항을 데이터베이스에 자동으로 반영하는 기능. 영속 상태의 엔티티에만 적용

 

    스냅샷 : 최초 상태를 복사해서 저장해두는 것 → 플러시 시점에 스냅샷과 엔티티를 비교해서 변경사항 수정 쿼리 작성

    

    이때 default = 엔티티의 모든 필드 업데이트 (항상 쿼리 동일하게 유지)

    동적 update-sql 생성하고 싶다면, DynamicUpdate 혹은 DynamicInsert 하이버에이트 확장 기능 이용

 

●  지연 로딩


준영속

: 영속성 컨텍스트가 제공하는 기능 사용 불가능

 

특징

●  식별자 값을 가지고 있음 : 이미 한 번 영속 상태였으므로 반드시 식별자 값을 가지고 있음

●  지연 로딩을 할 수 없음 

 

준영속 상태로 만드는 법

●  em.detach(entity) : 특정 엔티티만 준영속 상태로 전환

    이 메소드를 호출하는 순간 1차 캐시부터 쓰기 지연 SQL 저장소까지 해당 엔티티를 관리하기 위한 모든 정보가 제거됨.

●  em.clear() : 영속성 컨텍스트를 완전히 초기화 (= 해당 영속성 컨텍스트의 모든 엔티티를 준영속 상태로 만듬)

●  em.close() : 영속성 컨텍스트 종료

 

em.clear() 와 em.close() 의 차이

clear()의 경우 트랜잭션이 유지되지만, em.close()의 경우 트랜잭션이 종료되며 해당 entityManager의 인스턴스도 더 이상 사용할 수가 없음

 

병합: merge()

:: 준영속/비영속 상태의 엔티티를 영속 상태로 변경 'save or update'

merge()는 준영속 상태의 엔티티 정보를 가지고 새로운 영속 상태 엔티티를 반환 (= 다른 인스턴스)

 

○  준영속화 시켜서 준영속 상태에서 엔티티를 수정하고 병합(merge)하면 반영되지 않았던 변경 사항이 다시 영속성 컨텍스트에 반영됨

○  파라미터로 넘어온 엔티티는 병합 후에도 준영속 상태로 남아있음


출처

https://product.kyobobook.co.kr/detail/S000000935744

 

자바 ORM 표준 JPA 프로그래밍 | 김영한 - 교보문고

자바 ORM 표준 JPA 프로그래밍 | 자바 ORM 표준 JPA는 SQL 작성 없이 객체를 데이터베이스에 직접 저장할 수 있게 도와주고, 객체와 관계형 데이터베이스의 차이도 중간에서 해결해준다. 이 책은 JPA

product.kyobobook.co.kr

 

참고

https://shuu.tistory.com/130

 

커넥션 풀이란 (Connection Pool)

1) 커넥션 풀 (Connection Pool) (1) 커넥션 풀이란 JDBC API를 사용하여 데이터베이스와 연결하기 위해 Connection 객체를 생성하는 작업은 비용이 굉장히 많이 드는 작업 중 하나이다. Connection 객체를 생성

shuu.tistory.com

 

'Spring' 카테고리의 다른 글

연관관계 매핑(1)  (0) 2025.04.05
내 첫 스프링 CRUD 만들기  (0) 2025.04.04
이펍 세미나(1)  (0) 2025.04.01
엔티티 매핑  (0) 2025.03.30
JPA 프로그래밍  (1) 2025.03.16