오늘 스탠바드 반 세션에서 Transaction에 대해서 배웠다
오늘은 영속성 컨텍스트의 전체적인 맥락을 정리해보려고한다
ORM(Object-Relational Mapping)은 객체 지향 프로그램(OOP)방식과 관계형 데이터 베이스(RDB)의 차이를 해결하기 위해 등장한 기술이다
자바에서는 JPA(Java Persistence API), Hibernate, MyBatis 같은 ORM 프레임워크를 사용하여 객체와 데이터베이스 간의 매핑을 쉽게 관리할 수 있다
ORM의 핵심 개념은 아래와 같다
1. 객체와 테이블의 매핑
객체(Object)는 클래스(Class)로 표현되고, 테이블을 데이터베이스의 개념이다
ORM은 클래스와 테이블을 1:1로 매핑하여 SQL을 직접 작성하지 않아도 데이터베이스 작업을 할 수 있도록 한다
2. 자동 SQL 생성 및 실행
CRUD(Create, Read, Update, Delete) 쿼리를 직접 작성하지 않고 ORM이 자동으로 생성 및 실행합니다
예: save((), findById(). delete() 등의 메서드를 제공하여 개발자가 SQL을 신경 쓰지 않고도 데이터 조작 기능
3. 영속성(Persistence) 관리
영속성 컨텍스트(Persistence Context)를 통해 엔티티 객체를 캐싱하고, 변경 사항늘 감지하여 자동으로 데이터베이스에 반영(Dirty Checking)한다
4. 트랜잭션 관리
ORM 프레임 워크는 트랜잭션을 자동으로 처리하여 데이터의 일관성을 유지한다

Java의 대표적 ORM 프레임워크에는 자바의 공식 ORM 표준인 JPA(Java Persistence API)이 있다
JPA는 인터페이스 기반의 ORM 기술이고 보통 Hibernate 와 같은 JPA 구현체로 사용된다
객체 중심으로 데이터를 처리하고, JPQL(Java Persistence Query)을 지원하며, 트랜잭션 관리가 용이하다는 장점이 있다
또한 ORM을 사용할 때 SQL을 직접 작성할 필요가 없고 자바 기반의 객체 조작으로 데이터베이스 작업이 가능하다
그에 따라 객체 지향적인 코드로 유지보수가 용이해진다
ORM은 특정 데이터베이스 벤더(MySQL, PostgreSQL, Oracle 등), DBMS에 종속되지 않는다
JPA에서는 테이블과 매핑되는 엔티티 객체 정보를 영속성 컨텍스트를 통해 애플리케이션 내에서 오래 지속되도록 보관한다
JPA에서는 트랜잭션이 영속성 컨텍스트의 범위를 결정하며, @Transactional을 사용하면 트랜잭션이 유지되는 동안 영속성 컨텍스트가 활성화된다
영속성 컨텍스트(Persistense Context)는 논리적인 개념으로, JPA에서 엔티티를 영구 저장하는 환경을 의미한다
어플리케이션과 데이터베이스 사이에서 엔티티 객체를 보관하는 가상의 데이터베이스 같은 역할을 한다
엔티티 매니져를 통해 엔티티를 저장하거나 조회하면 엔티티 매니져는 영속성 컨텍스트에 엔티티를 보관하고 관리한다

영속성 컨텍스트의 특징은 엔티티 매니져를 생성할 떄 하나 만들어진다는 것이다
또한 엔티티 매니져를 통해서 영속성 컨텍스트에 접근하고 관리할 수 있다
영속성 컨텍스트의 가장 큰 특징은 엔티티 생명주기를 관리한다는 것이다
EntityManager 생성 방법
EntityManagerFactory: 설정 파일에서 작성한 persistence-unit(DB 설정 정보)로 생성한다
EntityManager: EntityManagerFactory에서 생성한다
엔티티는 비영속(new) -> 영속(managed) -> 준영속(detached) -> 삭제(removed)의 생명주기를 갖는다
비영속(transient/persist): 영속성 컨텍스트와 전혀 관계가 없는 상태
객체가 생성된 시점이다
엔티티가 영속성 컨텍스트에 없는 상태이다
영속(merge): 영속성 컨텍스트에 저장된 상태/em.persist(객체)
엔티티가 영속성 컨텍스트에 저장된 시점이다
영속성 컨텍스트가 엔티티를 관리한다
준영속(detached): 영속성 컨텍스트에 저장되었다가 분리된 상태/em.detach(객체)
엔티티가 영속 상태에서 준영속 상태로 간 상태이다
영속성 컨텍스트가 엔티티를 관리하지 않고, 따라서 영속성 컨텍스트가 제공하는 기능을 사용하지 못한다
*준영속 상태로 만드는법
em.detach(entity); : 특정 엔티티만 준영속 상태로 변환된다
em.clear(); :영속성 컨텍스트를 초기화한다(모든 엔티티를 삭제)
em.close(); : 영속성 컨텍스트를 종료한다
삭제(removed): 삭제된 상태/em.remove(객체)
영속성 컨텍스트에 있는 엔티티를 삭제한다
이때 DB에서도 삭제된다
트랜잭션이 끝나거나 EntityManager를 flush 하기 때문에 삭제 쿼리가 나가야 DB에서 삭제된다
영속성 컨텍스트는 아래와 같은 장점을 갖는다
1. 1차 캐시
영속성 컨텍스트는 같은 트랜잭션 내에서 엔티티를 1차 캐시에 저장한다
캐시는 map 형태로 key-value를 저장한다
key: DB의 PK, value: 객체
같은 엔티티를 다시 조회할 경우, 데이터베이스가 아니라 1차 캐시에서 가져와 성능을 최적화한다
그러나 1차 캐시가 있는 EntityManager는 트랜잭션 단위로 만들고 사라져서 캐시 메모리에 저장된 시간이 매우 짧아 성능에는 효과가 업다
또한 트랜잭션마다 서로 다른 EntityManager를 사용하고 따라서 서로 다른 영속성 컨텍스트와 1치 캐시를 가지기 때문에 큰 도움이 되지 않는다
2. 동일성/ACID의 Conistency 보장
같은 트랜잭션 안에서 같은 객체는 == 비교를 보장한다
3. 변경 감지(Dirty Checking)
flush() 호출 시, 엔티티의 변경 사항을 자동으로 감지하고 JPA가 쿼리문을 날려 데이터베이스에 반영한다
따라서 값 변경 후 update 쿼리문을 날릴 코드를 작성하지 않아도 된다
4. 지연 로딩(Lazy Loading)
즉시 로딩과 지연 로딩의 개념이 있는데, 즉시 로딩은 엔티티를 조회할 때 연관된 객체도 함께 DB에서 조회한다
지연 로딩은 연관된 객체는 조회하지 않고 나중에 필요하면 그 때 DB에서 조회한다
commit()을 호출할 때까지 SQL 쿼리를 모아두고 한 번에 실행하여 성능을 최적화한다
각 연관 관계마다 즉시 로딩, 지연 로딩 설정이 가능하다(FetchType enum으로 가능하다)

오늘 하루도 하나 알아가서 좋다
내일도 화이팅 해보자 ~ !
'[Kotlin&Spring] 5기 내일배움캠프' 카테고리의 다른 글
| [Kotlin&Spring] 5기 운영체제의 개념을 알아보자 (1) | 2025.02.07 |
|---|---|
| [Kotlin&Spring] 5기 싱글톤 패턴과 Spring Framework에서 단점 해결 방안 (1) | 2025.02.06 |
| [Kotlin&Spring] 5기 SchedulingApp 트러블슈팅 Annotation (2) | 2025.02.04 |
| [Kotlin&Spring] 5기 HTTP: Datatracker RFC9110 소개와 주요 용어 (1) | 2025.01.31 |
| [Kotlin&Spring] 5기 관계형 데이터 베이스와 SQL (0) | 2025.01.27 |