주의할점
영속성 컨텍스트 및 Dirty Checking 개념을 이해하지 못하고 사용하면
데이터 손실 및 성능 이슈가 있을 수 있다.
JPA의 모든 데이터 편경은 트랜잭션 안에서 실행된다. @Transactional
즉, 트랜잭션 밖에서 데이터 변경은 반영되지 않는다.
영속성 컨텍스트 Persistence Context
애플리케이션과 데이터베이스 사이에서 엔티티와 레코드의 괴리를 해소하는 기능과 객체를 보관하는 기능을 수행한다..
entity를 저장하고 관리하는 저장소 (가상의 데이터베이스 역할)
이미 영속상태인 경우 merge를 통해 덮어쓴다.
영속 객체 Persistence Object
엔티티 객체가 영속성 컨텍스트에 들어와 JPA의 관리 대상이 되는 시점부터의 객체
영속성 컨텍스트는 세션 단위의 생명주기를 가진다.
데이터베이스에 접근하기 위한 세션 생성 -> 영속성 컨텍스트 생성 -> 세션 종료 -> 영속성 컨텍스트도 사라진다.
엔티티 매니저
엔티티를 관리하는 객체
데이터베이스에 접근해서 CRUD 작업을 수행한다.
- 엔티티의 생명주기
- 비영속 New : 영속성 컨텍스트에 추가되지 않은 엔티티 객체의 상태
- 영속 Managed : 영속성 컨텍스트에 의해 엔티티 객체가 관리되는 상태
- 준영속 Detached : 엔티티 객체가 컨텍스트와 분리된 상태
- 삭제 Removed : 영속성 컨텍스트에 삭제 요청을 한 상태
영속성 컨텍스트를 사용하는 이유?
1. 1차 캐시
persist를 하는 순간 pk값, 타입과 객체를 맵핑하여 1차 캐시에 가지게 된다.
한 트랜잭션 내에 1차 캐시에 이미 있는 값을 조회하는 경우 DB 조회하지 않고 1차 캐시에 있는 내용을 그대로 가져온다.
(단 1차 캐시는 한 트랜잭션 내에서만 공유)
1차 캐시에 없다면 DB에서 가져와서 1차 캐시에 저장 후 반환한다.
2. 쓰기 지원 SQL 저장소
memberA를 persist 하는 순간, 1차 캐시에 넣고 쓰기 지연 SQL 저장소에 쿼리를 만들어 쌓는다.
memberB도 동일한 과정을 거치며 commit 하는 순간 flush가 호출되면서 DB에 반영
flush : 영속성 컨텍스트의 변경 내용을 DB에 반영하며 1차 캐시를 지우지 않는다.
3. 엔티티 수정 Dirty Checking
코드에서 엔티티의 값만 변경했는데 데이터베이스 업데이트 쿼리가 발생한다?!
이유는 Dirty Checking 덕분이다.
Dirty : 엔티티 데이터의 변경된 부분
JPA에서 트랜잭션이 끝나는 시점에 변화가 있는 모든 entity 객체 상태를 검사하여 반영한다. (엔티티와 스냅샷을 비교한다.)
1차 캐시에는 처음 들어온 상태인 엔티티 스냅샷을 넣어두고
commit하는 순간 변경된 값이 있는지 비교하여
변경된 값이 있으면 update 쿼리를 쓰기 지연 SQL에 넣어둔다.
Dirty checking 주의사항
1. 영속성 컨텍스트가 관리하는 entity만 적용된다.
2. 영속 상태(Managed)가 아닐 경우에는 값을 변경해도 데이터베이스에 반영되지 않는다.
3. 트랜잭션 없이 데이터 반영이 일어나지 않는다.
'개발공부 > JAVA Spring' 카테고리의 다른 글
JPA Auditing (0) | 2023.01.21 |
---|---|
troubleshooting - Failed to load ApplicationContext (0) | 2023.01.19 |
Spring Data JPA, DAO, DTO, Entity, Repository 란? (0) | 2023.01.16 |
테스트 코드 작성 프레임워크 - Spock (0) | 2023.01.04 |
[springboot] redis, mariadb docker-compose (0) | 2022.12.18 |
댓글