[SPRINGBOOT-JPA] 영속성(persistence)

개발할래·2023년 10월 25일
0

개발

목록 보기
6/13

영속성이란

사전정의는 영속성(persistence)은 데이터를 생성한 프로그램의 실행이 종료되더라도 사라지지 않는 데이터의 특성을 의미한다. 영속성은 파일 시스템, 관계형 테이터베이스 혹은 객체 데이터베이스 등을 활용하여 구현한다.
영속성을 갖지 않는 데이터는 단지 메모리에서만 존재하기 때문에 프로그램을 종료하면 모두 잃어버리게 된다. 결국 영속성은 특정 데이터 구조를 이전 상태로 복원할 수 있게 해주어 프로그램의 종료와 재개를 자유롭게 해준다.
the characteristic of data that outlives the execution of the program that created it: which is achieved in practice by storing the data in non-volatile storage such as a file system or a relational database or an object database
영속성이 필요한 객체를 'persistent object'라고 하는데, 필요없는 객체는 어떻게 표기할까? 먼저 위키피디아에서는 반대 표현을 ephemeral이라 한다. 처음보는 형용사인데, 영속성이 불필요한 데이터 구조를 수식할 때 사용하는 것이다.

1차 캐시

JPA에서 1차 캐시는 EntityManager가 관리하는 영속성 컨텍스트 내부에 있는 첫 번째 캐시입니다.

EntityManager는 Thread-safety하지 않으므로, per thread로 바인딩됩니다. 즉, 각 쓰레드의 1차 캐시는 별도로 동작하는 것을 전제로 합니다.

1차 캐시의 조회 동작은 아래와 같습니다.

조회 시 1차 캐시에 데이터가 이미 있는지 확인하고, 데이터가 있으면 가져온다. (비교는 PK로 한다.)
1차 캐시에 데이터가 없다면, 데이터베이스에 데이터를 요청한다.
데이터베이스에서 받은 데이터를 다음에 재사용할 수 있도록 1차 캐시에 저장한다.

Q] Update가 발생하면 데이터가 갱신될텐데, 캐시에 있는 것을 조회하면 과거의 데이터만 받는거 아닌가요?

A] 1차 캐시는 영속성 컨텍스트 내부에 있습니다. 영속성 컨텍스트 내부에 있는 엔터티의 변화가 즉시 1차 캐시에 저장되기 때문에, 캐시에서 갱신된 데이터를 받게 됩니다.

변경 감지
영속성 컨텍스트가 관리하는 엔터티가 수정되면 지연 SQL 저장소에 쿼리문이 저장됩니다.

플러시
Flush가 발생하면 쌓인 지연 SQL 저장소에 있는 쿼리들을 즉시 DB에 날립니다. 즉, 그동안의 변경사항을 Flush가 일어날 때 한번에 기록합니다. 따라서, DB 접근 빈도를 최소화할 수 있습니다. 이를 쓰기 지연이라고 합니다.

아래의 3가지 경우 중 1가지라도 발생되면 Flush가 발생합니다.

  • Transaction.commit()
  • entityManager.flush()
  • JPQL 쿼리 실행

쿼리문을 모아서 보낼 단위는 hibernate.jdb.batch_size속성의 수치를 변경해서 설정할 수 있습니다.

즉, 쓰기 동작은 아래와 같이 동작합니다.

  • 데이터가 변경되면 즉시 1차캐시에 반영한다.
  • 변경 사항이 지연 SQL 저장소에 저장된다.
  • Transaction이 commit되면 Flush가 발생한다.
  • 지연 SQL 저장소에 있는 SQL문을 DB에 요청한다.

이런 영속성은 장점이기도 하지만, JPA를 조심해서 사용해야 하는 이유입니다.

@Transactional

예를 들어, JPA는 save()문이나 update()문을 사용하지 않아도, 트랜잭션이 커밋되면 엔터티의 변경을 감지해서 DB를 갱신합니다. 변경이 반영되지 않겠다고 생각해서, 엔터티의 필드를 변경하다간 큰일날 수 있습니다.

profile
내 인생부터 개발

0개의 댓글