영속성이란?

이선우·2024년 9월 28일
0

개발 관련 지식

목록 보기
11/13

영속성이란 JPA를 공부하면서 많이 접하게 되는 용어이다.
영속성은 JPA가 제공하는 핵심 개념 중 하나로, 데이터베이스와 자바 애플리케이션 간의 데이터 저장과 관리를 의미한다. 이를 통해서 데이터베이스의 레코드를 자바 객체로 다루면서, 객체 지향적인 방법으로 데이터베이스 조작을 할 수 있게 된다.

JPA에서의 영속성에 대해 주요 개념을 추가로 설명해보겠다.

1. 영속성 컨텍스트

영속성 컨텍스트는 엔티티 객체를 관리하는 일종의 메모리 공간이다. 엔티티 매니저가 이 영속성 컨텍스트를 통해서 엔티티의 상태를 관리한다. 영속성 컨텍스트는 JPA에서 데이터의 일관성을 보장하는 중요한 역할을 하며, 여기서 관리되는 엔티티들은 영속 관계에 놓인다.

영속성 컨텍스트의 장점

  • 1차 캐시: 영속성 컨텍스트는 엔티티를 메모리에 캐시해서 중복 조회를 방지하고 성능을 최적화시켜준다.
  • 변경 감지: 엔티티의 상태가 변경되면 자동으로 감지되어, 트랜잭션이 커밋될 때 자동으로 데이터베이스에 반영된다.
  • 지연 로딩: 필요한 시점에만 데이터베이스에서 데이터를 조회하는 방식으로 성능을 최적화할 수 있다.

2. 엔티티와 영속성

  • 엔티티는 데이터베이스의 테이블과 매핑된 자바 객체로, JPA를 사용하면 이 객체를 통해 테이블의 데이터를 조작한다. JPA는 엔티티의 생명주기를 기반으로 엔티티의 상태를 관리하는데, 이를 통해 영속성과 관련된 여러 상태 변화를 관리할 수 있다

3. 엔티티의 생명주기

JPA에서 엔티티 객체는 네 가지의 생명주기를 가진다.

  1. 비영속 상태 Transient
    엔티티 객체가 영속성 컨텍스트와 전혀 연과되어 있지 않은 상태이다. 자바 객체로는 존재하지만, 데이터베이스와 연관되어 있지 않은 상태를 말한다. 예를 들어서 new 키워드를 사용해서 새로 생성한 엔티티는 비영속 상태이다.

  2. 영속 상태 Persistent
    엔티티가 영속성 컨텍스트에 저장된 상태로, 데이터베이스에 반영될 준비가 된 상태이다. 이 상태에서는 영속성 컨텍스트가 엔티티를 관리하며, 자동으로 변경 사항을 데이터베이스에 반영한다.
    예를 들어서 entityManager.persist(entity)를 호출하면 엔티티가 영속 상태로 전환된다

  3. 준영속 상태 Detached
    영속성 컨텍스트에 의해 관리되던 엔티티가 더 이상 관리되지 않는 상태이다. 즉 데이터베이스와의 동기화가 끊긴 상태이다.
    예를 들어서 entityManger.detach(entity)를 호출하거나 entityManger.clear()로 전체 컨텍스트를 비울 때 엔티티가 준영속 상태가 된다.

  4. 삭제 상태 Removed
    마지막 상태로 엔티티가 영속성 컨텍스트에서 삭제되어 데이터베이스에서도 삭제될 준비가 된 상태이다. entityManager.remove(entity) 를 호출하면 엔티티가 상태 상태가 된다.

아마 엔티티의 생명주기를 읽으면서 나는 EntityManager를 직접 사용한적이 없는데 생명주기를 이용안한건가?? 라는 생각을 할 수도 있지만 JPA를 사용한다면 EntityManager를 내부적으로 사용하면서 개발자가 직접 EntityManger를 다루지 않고도 쉽게 JPA의 기능을 활용할 수 있도록 도와준다고 한다.

public interface MemberRepository extends JpaRepository<MemberEntity, Long> {
    // 기본 CRUD 메서드가 자동으로 제공됨
    Optional<MemberEntity> findByUsername(String username);
}

예를 들어서 위의 코드에서는 JpaRepository 인터페이스를 상속받기만 하면 자동으로 EntityManager를 사용해서 데이터베이스와 상호작용하는 메서드를 제공하기 때문에 EntityManager를 직접 다룰 필요가 없다

4. 트랜잭션과 영속성

  • JPA는 트랜잭션을 기반으로 엔티티의 상태를 데이터베이스에 반영한다 트랜잭션이 커밋될 때 영속성 컨텍스트는 모든 변경 사항을 데이터베이스에 적용한다
  • 추가로 트랜잭션 내에서만 엔티티가 영속성 컨텍스트에 의해 관리되므로, 트랜잭션이 끝나면 영속성 컨텍스트도 더 이상 존재하지 않는다

5. 플러시 Flush

  • Flush는 영속성 컨텍스트에 있는 변경 사항을 데이터베이스에 반영하는 작업을 의미한다. 기본적으로 JPA는 트랜잭션이 커밋되기 전에 플러시를 수행해서 엔티티의 변경사항을 자동으로 데이터베이스에 동기화한다. 개발자가 필요에 따라 flush() 메서드를 호출해서 수동으로 플러시를 할 수도 있다
  • 주의 해야 할점은 플러시는 영속성 컨텍스트의 변경 사항을 데이터베이스에 반영하지만, 트랜잭션을 커밋하지 않으면 그 데이터는 데이터베이스에 반영되지 않고 롤백될 수 있다.

6. 변경 감지 Dirty Checking

변경 감지 즉 Dirty Checking 이란 용어도 개발을 진행하면서 자주 들었지만 어떤 용어인지는 잘 몰랐던 용어인데, JPA가 영속 상태의 엔티티 객체가 변경되었을 때 자동으로 이를 감지하여, 트랜잭션 커밋 시점에 데이터베이스에 업데이트한다. 이러한 로직을 Dirty Checking이라고 한다. 이 과정에서 @Entity 객체의 필드 값이 변경되었는지를 추적한다.
Dirty Checking은 성능을 최적화하고 데이터 일관성을 보장하기 위해 매우 중요한 개념이라고 한다

7. Lazy Loading & Eager Loading

Lazy Loading 즉 지연 로딩은 위에서도 언급한 용어인데, 연관된 엔티티나 데이터를 실제로 사용할 때 데이터베이스에서 조회하는 방식이다. 필요하지 않은 데이터를 미리 로드하지 않기 때문에 성능 상의 이점이 있다

Eager Loading 은 즉시 로딩이라고 하는데 연관된 엔티티나 데이터를 즉시 데이터베이스에서 가져오는 방식이다. 기본적으로 모든 관련 엔티티가 함께 로드되기 때문에 성능 저하가 발생할 수 있다

두 개의 용어를 언제 사용하냐면 보통 엔티티 관계에서 @OneToMany@ManyToOne 등의 관계를 설정할 때 많이 사용했다.

그래서 만약에 누군가가 너 JPA에서의 영속성영속성 컨텍스트가 뭐야? 라고 묻는다면

영속성은 데이터를 데이터베이스에 영구적으로 저장되어서 애플리케이션이 종료되더라도 유지되는 것이고, 영속성 컨텍스트란 엔티티 객체를 관리하고 트랜잭션이 진행되는 동안 데이터베이스와의 동기화를 처리하는 메모리 공간이야 정리하자면 영속성 컨텍스트는 애플리케이션이 실행되는 동안만 메모리에서 엔티티 객체를 관리하는 일종의 임시 저장소라 애플리케이션이 종료되면 영속성과 다르게 사라져!!

라고 말할 수 있어야 할 것 같다.

profile
백엔드 개발자 준비생

0개의 댓글