본문 바로가기
Web/JPA

[JPA] 영속성 컨텍스트 (Persistence context)

by foreverever 2019. 5. 28.
반응형

1. 영속성(Persistence)

  • 데이터를 생성한 프로그램이 종료되도, 데이터는 사라지지 않는 특성
  • JPA에서 영속성이라 함은 Entity를 영구적으로 저장해주는 특성을 말함

2. 영속성 컨텍스트(Persistence context)

  • Entity를 영구적으로 저장하는 환경(영역)
  • 엔티티 매니저(Entity Manager)를 하나 생성할 때 영속성 컨텍스트 하나가 생성됨
  • 엔티티 매니저로 엔티티를 CURD함 (영속성 컨텍스트를 관리함)

특징

 1. 1차 캐시
 - 영속성 컨텍스트에 존재하는 캐시
 - 엔티티를 식별자 값(@id)로 구분
 - Key-value형태인 맵으로 저장 (@id는 key값, value는 Entity 인스턴스)
 - 영속상태의 엔티티는 반드시 식별자값을 가짐

 2. 동일성 보장
 - 동일한 객체 반환 (싱글톤)

 3. 쓰기지연 수행
 - 트랜잭션 범위 안에서 동작
 - 트랜잭션 commit 전, 영속성 컨텍스트의 sql저장소에 생성쿼리를 저장
 - flush() 수행 후, 저장했던 생성쿼리를 데이터베이스에 반영 (데이터베이스 동기화)
 - 트랜잭션 commit 

 4. 변경 감지
 - 영속성 컨텍스트에 있는 모든 엔티티를 스냅샷과 비교해서 수정된 엔티티를 찾는다. 
 - 수정된 엔티티를 확인하면, 수정 쿼리를 만들어 sql저장소에 저장
 - flush() 수행 후, 저장했던 수정쿼리를 데이터베이스에 반영 (데이터베이스 동기화)
 - 트랜잭션 commit

3. 엔티티 매니저(Entity Manager)

  • 말 그대로 엔티티 관리 객체
  • 엔티티 CRUD 작업 수행

3.1 등록 (쓰기지연)

transaction.begin();    //트랜잭션 시작

entityManger.persist(a);
entityManger.persist(b);
//쿼리를 DB에 보내지 않고, 영속성 컨텍스트의 sql저장소에 저장함 --> 쓰기지연

transaction.commit()    //트랜잭션 커밋 (모아둔 쿼리를 DB에 보냄)

3.2 조회 (1차 캐시, 동일성 보장)

엔티티 조회

transaction.begin();    //트랜잭션 시작

Person person = new Person();   //비영속 상태 (객체 생성) 
person.setId(1);

entityManager.persist(person);  //영속 상태 (1차 캐시에 저장)

Person person1 = entityManager.find(Person.calss, 1);   //1차 캐시 조회

Person person2 = entityManager.find(Person.calss, 2);   //1차 캐시에 존재하지 않는 엔티티 조회

//1. 1차 캐시에서 id(식별자)가 2인 엔티티 조회
//2. 1차 캐시에 존재하지 않으므로, DB에서 조회
//3. DB에서 조회한 엔티티를 1차 캐시에 저장
//4. 엔티티 반환

transaction.commit();    //트랜잭션 커밋

엔티티 동일성 보장

//id(식별자)가 같은 엔티티 2번 조회
Person taesu = entityManager.find(Person.calss, 1);
Person forever = entityManager.find(Person.calss, 1);

System.out.println(taesu == forever)    //true

3.3 수정 (변경 감지)

transaction.begin();    //트랜잭션 시작

Person findPerson = entityManager.find(Pserson.class, 1);

findPerson.setUserName("수태");
findPerson.setAge(23);

//entityManger.update(findPerson);   //update 메서드가 따로 존재하지 않음

transaction.commit();    //트랜잭션 커밋

수정과 관련된 메서드는 위 코드처럼 set메서드를 통해 데이터를 수정한다.
JPA는 엔티티를 영속성 컨텍스트에 보관할 때, 처음 상태를 저장해 두는 스냅샷 기능이 있다.
flush 시점에 스냅샷과 현재 엔티티 정보를 비교하여 변경된 엔티티를 찾는다.

3.4 삭제

transaction.begin();    //트랜잭션 시작

Person person = entityManger.find(Person.class, 1);
entityManger.remove(person);  //엔티티 삭제

transaction.commit()    //트랜잭션 커밋

4. 느낀점

flush와 commit의 차이가 확 와닿지가 않았다.
flush는 영속성 컨텍스트에 있는 엔티티 정보를 DB에 동기화를 하는 작업이며,
아직 트랜잭션 commit이 안됐기 때문에, 에러가 발생할 경우 롤백 할 수 있다.
반면, 트랜잭션이 commit이 된 이후에는 DB에 동기화된 정보는 영구히 반영되는, 즉 롤백 할 수 없는 상태가 되는 것이다.

결론은 공부를 더 하자

(참고 : https://stackoverflow.com/questions/14581865/hibernate-commit-and-flush)

반응형

'Web > JPA' 카테고리의 다른 글

[JPA] 지연 로딩/즉시 로딩  (0) 2019.06.20
[JPA] 트랜잭션  (0) 2019.05.29