1. 영속성 컨텍스트
* Entity 객체를 효율적으로 쉽게 관리하기 위해 만들어진 공간이다.
* 오른쪽 캡처를 보면 개발자들은 EntityManager를 사용해서 Entity를 저장하고 조회하고 수정하고 삭제할 수 있다.
* EntityManager는 EntityManagerFactory를 통해 생성하여 사용할 수 있는데 EntityManagerFactory를 만들기 위해서는 DB에 대한 정보를 전달해야한다.
* 정보를 전달하기 위해서는 /resources/META-INF/ 위치에 persistence.xml 파일을 만들어 정보를 넣어두면된다.
(아래 예시는 스프링환경이 아니고 자바환경에서 하는중)
* 코드에 화살표 부분에 이름은 보통 프로젝트나 클래스 명으로 하는게 좋긴하다.
* 이제 실행 코드 부분에서 해당 코드를 호출하면 JPA는 persistence.xml 의 정보를 토대로 EntityManagerFactory를 생성하고, EntityManagerFactory생성한 emf로 createEntityManager()하면 EntityManager를 생성 할 수 있다.
EntityManagerFactory emf = Persistence.createEntityManagerFactory("memo");
EntityManager em = emf.createEntityManager();
2. 트랜잭션
* DB자체의 개념이고 트랜잭션은 sql데이터들을 가지고 있다가 하나라도 문제일어나면 다 취소하고, 다 안전하다면 나중 commit으로 한번에 데이터베이스에 데이터를 저장한다. 이를 하는 이유는 DB의 데이터들을 안전하게 관리하기 위해서이다.
3. JPA의 트랜잭션
* 영속성 컨텍스트에 Entity 객체들을 저장했다고 해서 DB에 바로 반영 되지는 않는다.
* JPA에서도 위에 DB트랜잭션처럼 영속성 컨텍스트로 관리하고 있는 변경이 발생한 객체들의 정보를 쓰기 지연 저장소에 전부 가지고 있다가 마지막에 SQL을 한번에 DB에 요청해 변경을 반영한다.
4. 영속성 컨텍스트의 기능
* 영속성 컨텍스트가 Entity 객체를 효율적으로 관리하기 위해 내부적으로 1차 캐시라는걸 사용한다
* 캐시 저장소를 사용하면 좋은 점이 DB 조회 횟수를 줄이고(이미 캐시에 id가 1인 apple객체 있는데 또 조회 한다할때 db에서 검색 안해도된다),동일한 객체 생성 안하도록 객체 동일성 보장한다.
* 캐시 저장소는 Map 자료구조 형태로 되어있고 key에는 @Id로 매핑한 기본 키, value에는 해당 Entity 클래스의 객체를 저장한다.
- Entity저장 -> em.persist(memo); 메소드가 호출되면 memo Entity 객체를 캐시 저장소에 저장
- Entity 조회 -> em.find(Memo.class, 1); 메소드로 캐시저장소 데이터 조회하는거고 매개변수 첫번째에는 entity객체,두번째에는 조회하려는 프라이머리키 id넣어준다.
-Entity 삭제 -> 먼저 find로 조회해오고 delete상태로 만든담 commit하면 delete sql이 db에 신호가서 db에서 삭제한다
5. 쓰기 지연 저장소
* JPA가 트랜잭션 처럼 SQL을 모아서 한번에 DB에 반영하기 위해 쓰기 지연 저장소를 만들어 SQL을 모아두고 있다가 트랜잭션 commit 후 한번에 DB에 반영한다.
6. em.flush()
* 쓰기 지연 저장소를 직접 DB에 반영 하고 싶을때 em.flush()를 한다.
* 쓰기 지연 저장소 commit() 하면 commit() 메소드안 flush() 가 있어서 그런지 자동으로 flush()
작업하는거였다.
* 밑에 예시를 보면 직접 em.flush후 et.commit하고 오른쪽 결과 보니 flush호출하면 sql 기록이 나오고 이제 쓰기 지연 저장소에 entity객체가 없으니 commit을 해도 할게 없어서 sql기록이 안나온다
7. 변경 감지(Dirty Checking)
* 영속성 컨텍스트에서 저장된 Entity가 변경될 때마다 Update SQL이 쓰기 지연 저장소에 저장되면 하나의 Update SQL로 처리할 수 있는 상황을 여러번 Update SQL을 요청하게 되기 때문에 비효율이다.
* 그래서 먼저 데이터 조회시 JPA는 영속성 컨텍스트에 Entity 최초 상태를 저장하고 사용자가 Entity 변경후에 commit할때
flush()가 호출되면 Entity의 현재 상태와 저장한 최초 상태를 비교하고 변경 내용이 있으면 Update SQL을 생성하여 쓰기 지연 저장소에 저장하고 모든 쓰기지연 저장소의 SQL을 DB에 요청하여 반영한다.
8. SpringBoot의 JPA
* SpringBoot 환경에서는 EntityManagerFactory와 EntityManager를 자동으로 생성해준다.
* entity매니저를 사용하고 싶을땐 @PersistenceContext 사용한다
public 클래스 A{
@PersistenceContext
EntityManager em;
}
* 스프링환경에서는 @Transactional(readOnly = true) 을 걸면 자동으로 트렌젝션을 적용해준다.
* 클래스에 @Transactional(readOnly = true) 적용하면 읽기만 하는거인데 클래스안 메소드 생성,수정,삭제등 작업할땐
@Transactional(readOnly = false) 또 적어줘야한다.
9. 영속성 컨텍스트와 트랜잭션의 생명주기
* 트랜잭션이 유지되는 동안은 영속성 컨텍스트도 계속 유지가 되기 때문에 영속성 컨텍스트의 기능을 사용할 수 있다.
* 만약 @Transactional 없거나 중간에 트랜잭션이 close해서 끝나면 영속성 컨텍스트가 유지되지 못해 오류 발생한다.
'Spring' 카테고리의 다른 글
Spring_4주차-(1) (0) | 2023.11.10 |
---|---|
Spring_3주차-(1) (0) | 2023.11.07 |
Spring_2주차-(1) (0) | 2023.11.02 |
Spring_1주차-(2) (0) | 2023.11.01 |
Spring_1주차-(1) (0) | 2023.10.31 |