Back-end/Spring

[Spring] 영속성 컨텍스트

poppy 2022. 1. 26. 23:19
반응형
영속성 컨텍스트란?
- 엔티티를 영구 저장하는 환경
- 엔티티 매니저를 통해서 영속성 컨텍스트에 접근할 수 있다

 

엔티티의 생명주기

1. 비영속

- 영속성 컨텍스트와 전혀 관계가 없는 새로운 상태

 

엔티티를 생성하기만 했으므로 영속성 컨텍스트에서 관리하는 상태가 아니다

Member member = new Member();
member.setId(1L);
member.setName("HelloA");

 

2. 영속

- 영속성 컨텍스트에 관리되는 상태

em.persist(member); // 엔티티를 영속성 컨텍스트에 저장

 

3. 준영속

- 영속성 컨텍스트에 저장되었다가 분리된 상태

em.detach(member); // 엔티티를 영속성 컨텍스트에서 분리

 

4. 삭제

- 영속성 컨텍스트에서 삭제된 상태

em.remove(member); // 엔티티를 영속성 컨텍스트에서 삭제

 

영속성 컨텍스트의 이점

1. 1차 캐시

- 엔티티를 영속하면 영속성 컨텍스트의 1차 캐시에 저장이 된다. 그래서 조회를 할 때 1차 캐시에 저장되어있다면 데이터베이스에서 조회할 필요 없이 바로 조회할 수 있다. 1차 캐시에 없다면 데이터베이스에서 조회한 후 1차 캐시에 저장한다.

 Member member = new Member();
 member.setId("member1");
 member.setUsername("회원1");
 
 em.persist(member); // 1차 캐시에 저장
 Member findMember = em.find(Member.class, "member1"); // 1차 캐시에서 조회

 

2. 영속 엔티티의 동일성 보장

1차 캐시에 저장되기 때문에 조회할 때 영속 엔티티의 동일성이 보장된다.

Member a = em.find(Member.class, "member1");
Member b = em.find(Member.class, "member1");

System.out.println(a == b); // 동일성 비교 true

 

3. 트랜잭션을 지원하는 쓰기 지연

데이터의 변경이 있다면 트랜잭션을 시작하고 데이터를 변경해야 한다. 데이터 변경을 해도 데이터베이스에 바로 반영되지 않는다. 데이터 변경 쿼리를 쓰기 지연 SQL 저장소에 저장해두고, 트랜잭션 커밋이 일어나는 순간 쓰기 지연 SQL 저장소에 있던 쿼리가 실행된다.

EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();

transaction.begin(); // 트랜잭션 시작

// 아직 데이터베이스에 INSERT 하지 않는다
em.persist(memberA);
em.persist(memberB);

transaction.commit(); // 트랜잭션 커밋, 커밋하는 순간 데이터베이스에 INSERT 한다

 

4. 변경 감지

영속성 컨텍스트가 변경 감지를 하기 때문에 em.update() 같은 코드가 없어도 데이터가 변경된다. 영속 엔티티를 수정하는 것만으로도 데이터베이스의 데이터가 변경되는 것이다. 이것이 가능한 이유는 영속성 컨텍스트에 스냅샷을 저장해두기 때문이다. 엔티티의 최근 상태를 저장해두는 스냅샷이 있어서 스냅샷과 엔티티가 달라지면 변경을 감지하고 데이터베이스에 반영한다.

EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin(); // 트랜잭션 시작

// 영속 엔티티 조회
Member memberA = em.find(Member.class, "memberA");

// 영속 엔티티 데이터 수정
memberA.setUsername("hi");
memberA.setAge(10);

transaction.commit(); // 트랜잭션 커밋
반응형