영속성 컨텍스트(Persistence Context)
💡영속성 컨텍스트(Persistence Context)란?

- Persistence = "영속성, 지속성"
- JPA에서 말하는 영속성 컨텍스트란, Entity 객체를 효율적으로 관리하기 위한 가상의 공간
Persistence를 객체의 관점으로 해석해 보자면 ‘객체가 생명(객체가 유지되는 시간)이나 공간(객체의 위치)을 자유롭게 유지하고 이동할수 있는 객체의 성질’을 의미

- 개발자들은 JPA를 사용하면, 직접 SQL을 작성하지 않아도 DB에 데이터를 저장하거나 조회할 수 있으며 수정, 삭제 또한 가능하다.

- 이러한 일련의 과정을 효율적으로 처리하기 위해 JPA는 영속성 컨텍스트에 Entity 객체들을 저장하여 관리하면서 DB와 소통한다.
- 영속성 컨텍스트에서 PK로 Entity들을 식별한다.
🔎 Entity란?
- JPA에서 관리되는 클래스 즉, 객체를 의미
- Entity 클래스는 DB의 테이블과 매핑되어 JPA에 의해 관리된다.
EntityManager

💡EntityManager
- EntityManager는 이름 그대로 Entity를 관리하는 관리자이다.
- 영속성 컨텍스트에 접근하여 Entity 객체들을 조작하기 위해서는 EntityManager가 필요하다.
- 개발자들은 EntityManager를 사용해서 Entity를 저장하고 조회하고 수정하고 삭제할 수 있다.
- Entity 저장, 조회, 수정, 삭제
- DB와 연결되는 SQL 실행을 대신 처리
- EntityManager는 보통 EntityManagerFactory로부터 생성해서 사용한다.
EntityManagerFactory

💡EntityManagerFactory
- EntityManager를 생성하는 공장(Factory)
- 보통 DB 하나당 하나의 EntityManagerFactory만 생성된다.
- 애플리케이션 실행 동안 살아있으며, 필요할 때마다 EntityManager를 만들어준다.
- EntityManagerFactory를 만들기 위해서는 DB에 대한 정보를 전달해야한다.
🔎 persistence.xml
- EntityManagerFactory를 만들기 위해 DB에 대한 정보를 전달해야할 때 사용하는 파일
- 정보를 전달하기 위해서는 /resources/META-INF/ 위치에 persistence.xml 파일을 만들어 정보를 넣어두면 된다.
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.2"
xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd">
<persistence-unit name="memo">
<class>com.sparta.entity.Memo</class>
<properties>
<property name="jakarta.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="jakarta.persistence.jdbc.user" value="root"/>
<property name="jakarta.persistence.jdbc.password" value="{비밀번호}"/>
<property name="jakarta.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/memo"/>
<property name="hibernate.hbm2ddl.auto" value="create" />
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.use_sql_comments" value="true"/>
</properties>
</persistence-unit>
</persistence>
➡️ Java에서의 사용 예시
EntityManagerFactory emf = Persistence.createEntityManagerFactory("memo");
EntityManager em = emf.createEntityManager();
- EntityManagerFactory emf = Persistence.createEntityManagerFactory("memo");
- 해당 코드를 호출하면 JPA는 persistence.xml 의 정보를 토대로 EntityManagerFactory를 생성한다.
- EntityManager em = emf.createEntityManager();
- 코드를 호출하면 EntityManagerFactory를 사용하여 EntityManager를 생성할 수 있다.
JPA의 트랜잭션
💡트랜잭션(Transaction)이란?

- DB 데이터의 무결성(Integrity) 과 정합성(Consistency) 을 보장하기 위한 논리적 단위
- 쉽게 표현하자면 DB의 데이터들을 안전하게 관리하기 위해서 생겨난 개념
🔎 특징
- 가장 큰 특징은 여러 개의 SQL이 하나의 트랜잭션에 포함될 수 있다는 점이다.
- 이때, 모든 SQL이 성공적으로 수행이 되면 DB에 영구적으로 변경을 반영하지만 SQL 중 단 하나라도 실패한다면 모든 변경을 되돌린다. (rollback)
🔎 MySQL 예시
START TRANSACTION; # 트랜잭션을 시작합니다.
INSERT INTO memo (id, username, contents) VALUES (1, 'Robbie', 'Robbie Memo');
INSERT INTO memo (id, username, contents) VALUES (2, 'Robbert', 'Robbert Memo');
SELECT * FROM memo;
COMMIT; # 트랜잭션을 커밋합니다.
SELECT * FROM memo;
- JPA는 DB의 이러한 트랜잭션 개념을 사용하여 효율적으로 Entity를 관리하고 있다.
💡JPA의 트랜잭션

- 영속성 컨텍스트에 Entity 객체들을 저장했다고 해서 DB에 바로 반영 되지는 않는다.
- DB에서 하나의 트랜잭션에 여러 개의 SQL을 포함하고 있다가 마지막에 영구적으로 변경을 반영하는 것 처럼 JPA에서도 영속성 컨텍스트로 관리하고 있는 변경이 발생한 객체들의 정보를 쓰기 지연 저장소에 전부 가지고 있다가 마지막에 SQL을 한번에 DB에 요청해 변경을 반영한다.
🔎 저장 성공 예시
@Test
@DisplayName("EntityTransaction 성공 테스트")
void test1() {
EntityTransaction et = em.getTransaction(); // EntityManager에서 EntityTransaction을 가져옵니다.
et.begin(); // 트랜잭션을 시작합니다.
try { // DB 작업을 수행합니다.
Memo memo = new Memo(); // 저장할 Entity 객체를 생성합니다.
memo.setId(1L); // 식별자 값을 넣어줍니다.
memo.setUsername("Robbie");
memo.setContents("영속성 컨텍스트와 트랜잭션 이해하기");
em.persist(memo); // EntityManager 사용하여 memo 객체를 영속성 컨텍스트에 저장합니다.
et.commit(); // 오류가 발생하지 않고 정상적으로 수행되었다면 commit 을 호출합니다.
// commit이 호출되면서 DB에 수행한 DB 작업들이 반영됩니다.
} catch (Exception ex) {
ex.printStackTrace();
et.rollback(); // DB 작업 중 오류 발생 시 rollback을 호출합니다.
} finally {
em.close(); // 사용한 EntityManager를 종료합니다.
}
emf.close(); // 사용한 EntityManagerFactory 를 종료합니다.
}
- ⚠️ 주의
- Entity Class는 DB와 매핑이 되는 객체이기 때문에, Setter같은 값을 변경하는 메서드 사용을 할 때 주의해서 꼭 필요한 곳에만 쓸 수 있도록 한다.
- 의도치 않게 Setter에 의해 데이터를 변경해 DB에 반영되는 실수가 생길 수 있다.
- JPA에서 트랜잭션의 개념을 적용하기 위해 EntityManager에서 EntityTransaction을 가져와 트랜잭션을 적용할 수 있다.
- EntityTransaction et = em.getTransaction();
- 해당 코드를 호출하여 EntityTransaction을 가져와 트랜잭션을 관리할 수 있다.
- et.begin();
- 트랜잭션을 시작하는 명령어
- et.commit();
- 트랜잭션의 작업들을 영구적으로 DB에 반영하는 명령어
- et.rollback();
- 오류가 발생했을 때 트랜잭션의 작업을 모두 취소하고, 이전 상태로 되돌리는 명령어
🔎 저장 실패 예시
@Test
@DisplayName("EntityTransaction 실패 테스트")
void test2() {
EntityTransaction et = em.getTransaction(); // EntityManager에서 EntityTransaction을 가져옵니다.
et.begin(); // 트랜잭션을 시작합니다.
try { // DB 작업을 수행합니다.
Memo memo = new Memo(); // 저장할 Entity 객체를 생성합니다.
memo.setUsername("Robbert");
memo.setContents("실패 케이스");
em.persist(memo); // EntityManager 사용하여 memo 객체를 영속성 컨텍스트에 저장합니다.
et.commit(); // 오류가 발생하지 않고 정상적으로 수행되었다면 commit을 호출합니다.
// commit이 호출되면서 DB에 수행한 DB 작업들이 반영됩니다.
} catch (Exception ex) {
System.out.println("식별자 값을 넣어주지 않아 오류가 발생했습니다.");
ex.printStackTrace();
et.rollback(); // DB 작업 중 오류 발생 시 rollback을 호출합니다.
} finally {
em.close(); // 사용한 EntityManager를 종료합니다.
}
emf.close(); // 사용한 EntityManagerFactory를 종료합니다.
}
- 식별자 값을 넣어주지 않아 오류가 발생한 경우 but, auto increment 조건이 설정된 경우 식별자 값을 직접 넣지 않아도 된다.
- 따라서 et.rollback(); 코드가 호출이되어 트랜잭션 작업 내용들이 취소된다.
- DB를 확인해보면 해당 작업이 반영되어있지 않은 것을 확인할 수 있다.
🔎 영속성 컨텍스트 Debugging
1️⃣ 테스트 시작 위치 가장 왼쪽을 클릭하여 빨간색 원을 만든다. 그리고 해당 원에 우측클릭 후 Thread 부분을 클릭한 다음 Make Default 클릭 후 Done을 누른다.

2️⃣ 초록색 화살표 시작 버튼을 클릭 후 Debug를 클릭

3️⃣ 체크 부분을 클릭하여 순차적으로 코드를 진행

4️⃣ em.persist(memo); 코드 호출 후 persistenceContext 위치에 memo 객체가 저장되어있음을 확인할 수 있다.

출처
https://teamsparta.notion.site/2-8-2252dc3ef5148138bc6cd0ca5c783ef5
챕터2-8 : 영속성 컨텍스트란 무엇일까? | Notion
영속성 컨텍스트란?
teamsparta.notion.site
'심화 > Spring' 카테고리의 다른 글
| [Spring] 영속성 컨텍스트의 기능 (업데이트 중..) (0) | 2025.10.14 |
|---|---|
| [Lombok] @AllArgsConstructor 사용을 지양하는 이유 (0) | 2025.10.07 |
| [Spring] JPA란 무엇일까? (0) | 2025.10.03 |
| [Spring] IoC Container와 Bean (0) | 2025.10.02 |
| [Spring] IoC(제어의 역전), DI(의존성 주입) (0) | 2025.10.01 |