영속성 컨텍스트의 이점
- 1차 캐시
- 동일성(identity) 보장
- 쓰기 지연 (transactional write-behind)
- 변경 감지 (Dirty Checking)
1차 캐시
영속성 컨텍스트는 내부에 1차 캐시를 가지고 있다.
Member 객체를 생성한 후 em.persist를 통해 member 객체를 영속성 컨텍스트에 넣으면
id와 함께 member객체 자체가 저장된다.

em.find를 통해 조회를 하면 JPA는 영속 컨텍스트에서 먼저 1차 캐시를 뒤진다.
1차 캐시에 있으면 바로 조회해 옴

다음으로 find(”member2”)로 member2를 조회한다.
member2가 1차 캐시에 없으면 DB를 조회한다. (member2는 DB에 있다고 가정)
그리고 DB에서 조회한 member2를 1차 캐시에 저장
그 다음 member2 반환
이후에 member2를 다시 조회하면 1차 캐시 안에 있는 member2 반환


출력

첫번째 조회(findMember1)할 때는 DB에서 가져오기 때문에 select쿼리가 나옴
두번째 조회(findMember2)할 떄는 1차 캐시에서 조회되기 때문에 select쿼리가 나오지 않음
findMember1을 하면 DB에서 가지고 와서 일단 영속성 컨텍스트에 올려놓음
findMember2를 하면(같은 객체 조회) 영속성 컨텍스트 안의 1차 캐시를 뒤진 후 반환
영속 엔티티의 동일성 보장
같은 식별자(ID)를 가진 엔티티 객체는 동일한 엔티티로 취급
findMember1과 findMember2를 == 비교하면 true가 나온다.

출력

쓰기 지연 (transactional write-behind)

memberA와 memberB를 순차적으로 넣었을 때 JPA에서 무슨일이 벌어지는지 살펴보자.
영속 컨텍스트 안에는 1차 캐시와 함께 쓰기 지연 SQL 저장소가 있다.
em.persist(memberA)를 하면 memberA가 일단 1차 캐시에 들어간다.
그러면서 동시에 JPA가 INSERT 쿼리를 생성한 후 쓰기 지연 SQL 저장소에 쌓아둔다.

em.persist(memberB)를 하면 이 때도 memberB를 1차 캐시에 저장
동시에 INSERT SQL을 생성해서 쓰기 지연 SQL 저장소에 쌓아둔다.

쓰기 지연 SQL 저장소에 쌓인 쿼리들은 transaction.commit()하는 시점에 flush되면서 DB에 날라간다.
transaction.commit()을 호출하면 flush()가 자동으로 호출


출력

============= 이후에야 insert문 출력됨
변경 감지(dirty-checking)
member의 이름을 바꾼 뒤에 em.persist(member)를 호출하지 않아도 된다.

출력

member.setName(”zbzbzb”)만 했는데 자동으로 update 쿼리가 나갔다
JPA는 변경 감지 기능으로 엔티티를 변경할 수 있다.
em.update같은 코드가 필요하다고 생각할 수 있다.
하지만 이 메서드는 없어도 된다.

transaction.commit()을 호출했을 때 발생하는 일
- 엔티티와 스냅샷 비교 (Change Detection)
- 변경된 엔티티 처리
- flush() 호출
- 트랜잭션 커밋

'Spring, JPA 🌱 > 김영한 JPA' 카테고리의 다른 글
[김영한 JPA] 준영속 상태 (detached) (0) | 2025.02.07 |
---|---|
[김영한 JPA] 플러시 (flush) (0) | 2025.02.07 |
[김영한 JPA] 영속성 컨텍스트 (Persistence Context) (1) | 2025.02.07 |
[김영한 JPA] JPA 구동 방식 (0) | 2025.02.07 |
영속성 컨텍스트의 이점
- 1차 캐시
- 동일성(identity) 보장
- 쓰기 지연 (transactional write-behind)
- 변경 감지 (Dirty Checking)
1차 캐시
영속성 컨텍스트는 내부에 1차 캐시를 가지고 있다.
Member 객체를 생성한 후 em.persist를 통해 member 객체를 영속성 컨텍스트에 넣으면
id와 함께 member객체 자체가 저장된다.

em.find를 통해 조회를 하면 JPA는 영속 컨텍스트에서 먼저 1차 캐시를 뒤진다.
1차 캐시에 있으면 바로 조회해 옴

다음으로 find(”member2”)로 member2를 조회한다.
member2가 1차 캐시에 없으면 DB를 조회한다. (member2는 DB에 있다고 가정)
그리고 DB에서 조회한 member2를 1차 캐시에 저장
그 다음 member2 반환
이후에 member2를 다시 조회하면 1차 캐시 안에 있는 member2 반환


출력

첫번째 조회(findMember1)할 때는 DB에서 가져오기 때문에 select쿼리가 나옴
두번째 조회(findMember2)할 떄는 1차 캐시에서 조회되기 때문에 select쿼리가 나오지 않음
findMember1을 하면 DB에서 가지고 와서 일단 영속성 컨텍스트에 올려놓음
findMember2를 하면(같은 객체 조회) 영속성 컨텍스트 안의 1차 캐시를 뒤진 후 반환
영속 엔티티의 동일성 보장
같은 식별자(ID)를 가진 엔티티 객체는 동일한 엔티티로 취급
findMember1과 findMember2를 == 비교하면 true가 나온다.

출력

쓰기 지연 (transactional write-behind)

memberA와 memberB를 순차적으로 넣었을 때 JPA에서 무슨일이 벌어지는지 살펴보자.
영속 컨텍스트 안에는 1차 캐시와 함께 쓰기 지연 SQL 저장소가 있다.
em.persist(memberA)를 하면 memberA가 일단 1차 캐시에 들어간다.
그러면서 동시에 JPA가 INSERT 쿼리를 생성한 후 쓰기 지연 SQL 저장소에 쌓아둔다.

em.persist(memberB)를 하면 이 때도 memberB를 1차 캐시에 저장
동시에 INSERT SQL을 생성해서 쓰기 지연 SQL 저장소에 쌓아둔다.

쓰기 지연 SQL 저장소에 쌓인 쿼리들은 transaction.commit()하는 시점에 flush되면서 DB에 날라간다.
transaction.commit()을 호출하면 flush()가 자동으로 호출


출력

============= 이후에야 insert문 출력됨
변경 감지(dirty-checking)
member의 이름을 바꾼 뒤에 em.persist(member)를 호출하지 않아도 된다.

출력

member.setName(”zbzbzb”)만 했는데 자동으로 update 쿼리가 나갔다
JPA는 변경 감지 기능으로 엔티티를 변경할 수 있다.
em.update같은 코드가 필요하다고 생각할 수 있다.
하지만 이 메서드는 없어도 된다.

transaction.commit()을 호출했을 때 발생하는 일
- 엔티티와 스냅샷 비교 (Change Detection)
- 변경된 엔티티 처리
- flush() 호출
- 트랜잭션 커밋

'Spring, JPA 🌱 > 김영한 JPA' 카테고리의 다른 글
[김영한 JPA] 준영속 상태 (detached) (0) | 2025.02.07 |
---|---|
[김영한 JPA] 플러시 (flush) (0) | 2025.02.07 |
[김영한 JPA] 영속성 컨텍스트 (Persistence Context) (1) | 2025.02.07 |
[김영한 JPA] JPA 구동 방식 (0) | 2025.02.07 |