2023.09.04 - 영속성 컨텍스트

mjjin·2023년 9월 4일
0

영속성 컨텍스트란?

영속성 컨텍스트는 엔티티를 영구 저장하는 환경이다. 일종의 논리적인 개념으로 눈에 보이지 않는다.
JPA를 이해하는데 가장 중요한 용어는 영속성 컨텍스트다.
엔티티 매니저를 생성할 때 하나 만들어진다.
영속성 컨텍스트의 이점

1차 캐시

엔티티를 영속성 컨텍스트에 저장하는 것을 1차 캐시라고 한다.
1차 캐시는 내부에 Map 형태로 구현되어 있다.
1차 캐시는 트랜잭션을 지원하는 쓰기 지연이나, 동일성 보장, 쓰기 지연 등의 다양한 기능을 제공하기 위해 필요하다.

동일성 보장

동일성 보장은 같은 트랜잭션 안에서는 같은 엔티티가 조회되는 것을 보장한다.
즉, 같은 트랜잭션 안에서는 같은 식별자를 가진 엔티티는 같은 엔티티로 인식한다.
동일성 비교는 == 비교로 할 수 있다.
트랜잭션을 지원하는 쓰기 지연
트랜잭션을 커밋할 때까지 INSERT SQL을 모음
JDBC BATCH SQL 기능을 사용해서 한 번에 SQL 전송

변경 감지

트랜잭션을 커밋할 때까지 UPDATE SQL을 모음
변경 감지 기능을 사용해서 필요한 UPDATE SQL을 찾아서 전송
변경된 데이터만 UPDATE SQL로 만들어서 보낸다.

지연 로딩

지연 로딩은 연관된 엔티티를 실제 사용할 때 로딩하는 것을 말한다.
즉, 연관된 엔티티를 사용할 때 SELECT SQL을 실행해서 데이터를 가져온다.
지연 로딩은 영속성 컨텍스트의 지연 로딩 기능과 JDBC의 연관 관계를 사용해서 구현한다.

쓰기 지연

쓰기 지연은 트랜잭션을 커밋할 때까지 INSERT, UPDATE, DELETE SQL을 모아서 보내는 기능이다.
쓰기 지연 SQL 저장소에 INSERT, UPDATE, DELETE SQL을 모아두었다가 트랜잭션을 커밋할 때 모아둔 SQL을 데이터베이스에 보낸다.
쓰기 지연 SQL 저장소는 영속성 컨텍스트에 있으며, 트랜잭션을 커밋하면 플러시가 호출되면서 데이터베이스에 쿼리를 전송한다.
영속성 컨텍스트의 생명주기

  • 비영속(new/transient) : 영속성 컨텍스트와 전혀 관계가 없는 상태
  • 영속(managed) : 영속성 컨텍스트에 저장된 상태
  • 준영속(detached) : 영속성 컨텍스트에 저장되었다가 분리된 상태
  • 삭제(removed) : 삭제된 상태

트랜잭션

트랜잭션은 데이터베이스의 상태를 변화시키기 위해 수행하는 작업의 단위이다.

트랜잭션의 특징

원자성

All or Nothing
트랜잭션의 작업이 모두 완료되거나, 아니면 전혀 어떠한 작업도 수행하지 않은 상태
트랜잭션의 작업이 부분적으로 실행되다가 중단되지 않는다.
트랜잭션의 작업이 완료되지 않으면 이전 상태로 롤백한다.
트랜잭션의 모든 연산이 정상적으로 실행되어야 한다.

일관성

트랜잭션의 작업 처리 결과가 항상 일관성이 있어야 한다.

격리성

트랜잭션은 독립적으로 수행되어야 한다.
트랜잭션 간에는 서로 영향을 미치지 않는다.
트랜잭션 수행 중에 다른 트랜잭션의 연산이 끼어들 수 없다.
트랜잭션 수행 중에 다른 트랜잭션의 연산 결과를 참조할 수 없다.
트랜잭션 수행 중에 다른 트랜잭션에 의해 변경된 데이터를 참조할 수 없다.

지속성

트랜잭션이 성공적으로 완료되면 그 결과는 영구적으로 반영되어야 한다.
시스템에 문제가 발생하더라도 데이터는 보존되어야 한다.
모든 트랜잭션은 로그로 남아있어야 한다.
트랜잭션의 성공적인 수행 후에는 로그에 기록된 모든 데이터가 영구적으로 저장되어야 한다.
트랜잭션의 결과는 영구적으로 반영되어야 한다.

JPA의 트랜잭션 관리 방법 2가지

JPA를 사용하지 않으면서 직접 트랜잭션을 관리하는 방법

JPA를 사용하지 않으면서 직접 트랜잭션을 관리하는 방법은 스프링의 트랜잭션을 사용하는 방법이다.
스프링의 트랜잭션은 PlatformTransactionManager 인터페이스를 사용해서 트랜잭션을 관리한다.
PlatformTransactionManager 인터페이스를 구현한 클래스는 DataSourceTransactionManager, JpaTransactionManager 등이 있다.

JPA를 사용해서 트랜잭션을 관리하는 방법

JPA를 사용해서 트랜잭션을 관리하는 방법은 @Transactional 어노테이션을 사용하는 방법이다.
스프링은 @Transactional 어노테이션을 사용하면 PlatformTransactionManager를 구현한 JpaTransactionManager를 사용해서 트랜잭션을 관리한다.
JPA를 사용하면 엔티티 매니저를 통해서 트랜잭션을 시작하고 종료한다.
트랜잭션을 시작하려면 엔티티 매니저를 통해서 트랜잭션을 얻어야 한다.
트랜잭션을 커밋하거나 롤백하면 트랜잭션 종료 후 다시 트랜잭션을 시작해야 한다.

0개의 댓글