영속성 컨텍스트 (Persistence Context)
일종의 JPA 컨테이너 안에서 동작하는 Entity의 Context를 관리하는 것.
Context내에서 CRUD가 일어나는데, 실제로 영속성 컨텍스트의 주체적인 역할을 하는 것은 Entity Manager
Bean이다.
EntityManager를 @Autowired
해서 사용할 수도 있다.
Spring Data JPA는 EM을 사용하지 않고 쿼리를 실행할 수 있도록 도와준다.
Spring DATA JPA에서 제공하지 않는 custom query는 EntityManager를 직접받아서 처리하면 된다.
1 |
|
위와 같이 실행하면 userRepository.finaAll()
을 실행한 것과 같은 결과가 나온다.
1차 캐시 (Id 값)
영속성 컨텍스트 내에서 Entity를 관리하는 Entity Manager는 캐시
를 가지고 있다.
Entity의 Id를 작업을 수행할 때 별도로 Cache 처리를 하지 않아도, 영속성 컨텍스트에서 자동으로 Entity에 대한 Cache처리를 해주는 것이다.
메서드에 @Transactional
을 설정하고, 조회를 여러 번 하는 코드를 작성하면 조회는 한 번만 하지만 데이터를 계속해서 가져올 수 있다. 이는 영속성 컨텍스트에 존재하는 Entity Cache에서 가져온 것이다.
메서드에 @Transactional
을 설정을 하지 않으면 JPA 메서드는 내부적으로 @Transactional
이 설정되어 있기 때문에, 실행할 때마다 캐시를 사용하지 않고 DB와 연동을 하게 된다.
예시
1 |
|
캐시 자료구조
1차 캐시는 Map 형태로 생성된다.
- Key는 id
- Value는 해당 Entity 가 들어있다.
Id 값으로 조회할 때 영속성 Context에 존재하는 1차 캐시에 존재하는지 체크하고, 있으면 캐시에서 가져오고, 없으면 DB 조회를 한다.
DB 반영 시점
flush()
메서드를 명시적으로 호출하는 시점Transaction
이 끝나서 쿼리가 commit 되는 시점JPQL
쿼리가 실행되는 시점
@Transactional
영속성 Context가 존재하여 JPA는 지연 쓰기
가 발생한다. 즉 save 하는 시점에 바로 DB에 반영되지 않는다.
@Transactional
이 존재하는 상태에서 delete
, update
를 실행하여도 조회만 일어나고, 이에 대한 쿼리는 발생하지 않는다.
EntityManager가 Entity의 상태를 merge하고, 최종적으로 반영해야 되는 내용에 대해서만 쿼리가 실행된다
Transaction이 묶여 있지 않으면, 메서드가 실행되는 도중에 실패하게 되면 앞에 있는 쿼리는 실행되고, 실행되지 못한 쿼리는 반영되지 않는 현상이 발생한다.
flush()
메서드를 통해 DB에 반영하는 시점을 정할 수 있다.
saveAndFlush()
메서드를 사용하면 저장과 동시에 반영할 수 있다.
설정
persistence.xml을 통한 설정
LocalContainerEntityManagerFactoryBean
클래스의 setPersistenceXmlLocation()
에 의해 resources - META-INF - persistence.xml
로 저장 위치와 파일 이름이 고정되어 있다.
application.yml을 통한 설정
dependency에 spring-boot-starter-data-jpa
를 추가하면 Spring Boot
가 Context에 대한 설정을 처리해준다.
이후에 application.yml 파일에서 설정을 할 수 있다.
영속성 컨텍스트 (Persistence Context)
install_url
to use ShareThis. Please set it in _config.yml
.