영속성 컨텍스트(Persistence Context)는 JPA에서 매우 중요한 개념입니다. '엔티티를 영구 저장하는 환경'이라는 뜻입니다.

JPA를 통해서 엔티티를 생성하고, 이를 데이터베이스에 저장하는 작업을 수행할 때, 이 엔티티는 영속성 컨텍스트에 저장되며, 이 상태를 '영속 상태'라고 합니다. 이렇게 영속성 컨텍스트에 저장된 엔티티는 데이터베이스와 일치하는 상태를 유지합니다. 이때 영속성 컨텍스트는 해당 엔티티를 관리하면서 발생하는 모든 변경사항을 데이터베이스에 동기화하게 됩니다.

1차 캐시는 영속성 컨텍스트 내부에 있는 캐시로서, 엔티티의 조회와 관련한 동작을 수행합니다. 영속성 컨텍스트는 엔티티를 저장하거나 조회할 때 먼저 1차 캐시에서 해당 엔티티를 찾아보고, 있다면 데이터베이스에 접근하지 않고 해당 엔티티를 반환합니다. 이런 방식으로 1차 캐시는 데이터베이스와의 불필요한 접근을 줄여 성능을 향상시킵니다.

하지만, 1 캐시는 해당 트랜잭션 범위에서만 유효하며, 트랜잭션이 종료되면 1 캐시의 엔티티들도 모두 사라지게 됩니다. 따라서, 1 캐시는 트랜잭션 범위에서의 재조회를 최적화하거나, 동일 트랜잭션 내에서의 엔티티 동일성을 보장하는 역할을 수행하게 됩니다.

 

1. 영속성 컨텍스트(Persistence Context)는 무엇인가요? 이를 사용하는 이유는 무엇인가요?

 

영속성 컨텍스트는 JPA에서 핵심적인 역할을 하는 개념으로, Entity를 영구 저장하는 환경을 의미합니다.

이 영속성 컨텍스트는 Entity Manager에 의해 관리되며, Entity Manager는 Entity를 저장, 수정, 삭제, 조회하는 기능을 제공합니다. 영속성 컨텍스트는 Entity의 생명주기를 관리하며, 해당 Entity에 대한 1차 캐시, 쓰기 지연, 변경 감지(Dirty Checking), 지연 로딩(Lazy Loading) 등의 역할을 수행합니다.

영속성 컨텍스트를 사용하는 이유는 아래와 같습니다:

  1. 1차 캐시: 영속성 컨텍스트는 조회한 Entity를 1차 캐시에 보관하므로, 같은 트랜잭션 내에서는 같은 Entity를 반환하도록 보장하며, 이를 통해 트랜잭션 내에서 데이터 일관성을 유지할 수 있습니다.
  2. 쓰기 지연: 영속성 컨텍스트는 트랜잭션을 커밋할 때까지 쓰기 지연 SQL 저장소에 저장된 쿼리를 데이터베이스에 보낼 것입니다. 이를 통해 네트워크 비용을 줄일 수 있고, 필요한 시점에만 데이터베이스에 접근할 수 있습니다.
  3. 변경 감지: 영속성 컨텍스트는 트랜잭션을 커밋하는 시점에 1차 캐시에 있는 Entity와 스냅샷을 비교하여 변경사항을 감지(Dirty Checking)하고, 이를 데이터베이스에 반영합니다. 이를 통해 개발자가 별도로 업데이트 쿼리를 작성할 필요 없이 Entity의 상태 변경만으로 데이터베이스와 동기화를 수행할 수 있습니다.
  4. 지연 로딩: 영속성 컨텍스트는 필요한 시점에 데이터를 로딩하는 지연 로딩을 지원합니다. 이를 통해 성능 최적화를 할 수 있습니다.

따라서 영속성 컨텍스트는 JPA 핵심 기능을 수행하며, 이를 사용함으로써 개발자는 객체 지향 프로그래밍에 집중하고, JPA 데이터 접근과 트랜잭션 관리를 대신해주기 때문에 생산성을 향상시킬 있습니다.

 

2. JPA에서 1차 캐시와 2차 캐시의 차이는 무엇인가요?

 

1차 캐시:

  • 1차 캐시는 영속성 컨텍스트 내부에 존재하는 캐시로서, Entity Manager가 관리하는 영역입니다. 한 개의 트랜잭션 범위에서만 동작하며, 트랜잭션을 시작하고 커밋하기까지의 범위에서 Entity를 관리합니다.
    Entity Manager에서 조회한 Entity는 1차 캐시에 저장되고, 이후 같은 Entity를 조회하려 하면 1차 캐시에서 우선적으로 조회하므로 데이터베이스 접근을 줄일 수 있습니다. 또한, 트랜잭션 커밋 시점에 변경 감지(Dirty Checking)를 통해 데이터베이스에 적절한 쿼리를 전송합니다.

2차 캐시:

  • 2차 캐시는 여러 트랜잭션과 여러 세션, 즉 여러 영속성 컨텍스트 간에 공유되는 캐시입니다. 이는 애플리케이션의 성능을 향상시키기 위한 전략으로, 자주 접근되는 데이터를 메모리에 보관하여 데이터베이스 접근을 최소화합니다.
    2차 캐시는 Entity Manager 간에 공유되므로, 다른 트랜잭션에서 이미 로딩된 Entity에 대한 정보를 재사용할 수 있습니다. 그러나 모든 Entity가 2차 캐시에 적합한 것은 아니며, 주로 읽기가 많고 변경이 잘 일어나지 않는 데이터에 대해 사용됩니다.
    2차 캐시는 JPA 표준 스펙에는 포함되어 있지 않지만, 대부분의 JPA 구현체(하이버네이트, EclipseLink 등)에서 지원하는 기능입니다.

따라서, 1 캐시와 2 캐시는 공통적으로 데이터베이스 접근을 최소화하여 애플리케이션의 성능을 향상시키는 역할을 하지만, 범위와 사용되는 상황에 있어서 차이가 있습니다.

 

더보기

1차 캐시는 사장님이 하루 동안 팔린 상품의 정보를 기록하는 메모장과 같습니다. 즉, 그날그날의 거래 내용을 잠시 기록해두는 곳입니다. 만약 오후에 같은 상품이 다시 팔리면, 아침에 기록해둔 정보를 참고하여 판매 수량을 늘리거나 재고를 확인할 수 있겠죠. 하지만 이 메모장은 하루가 끝나면 초기화되고 다음 날을 위해 새롭게 시작합니다.

이와 달리, 2차 캐시는 사장님이 매일의 판매 내역을 정리하여 1년 동안 쌓아두는 대형 서랍장과 같습니다. 이 서랍장에서는 지난 1년 동안 어떤 상품이 얼마나 팔렸는지, 어느 시즌에 어떤 상품이 잘 팔렸는지 등의 정보를 찾을 수 있습니다. 이런 정보는 상품 주문이나 마케팅 전략 등에 도움이 됩니다. 이 서랍장의 정보는 오래 보관되어 언제든 참고할 수 있습니다.

여기서 중요한 점은, 가지 캐시 모두 상품 판매 정보를 저장하고 있지만, 사용 목적과 저장 범위, 지속 시간이 다르다는 것입니다. 이처럼 JPA에서 1 캐시는 트랜잭션(하루의 거래) 동안 일시적으로 정보를 저장하고, 2 캐시는 여러 트랜잭션(1 동안의 거래) 걸친 정보를 보관합니다.

 

3. JPA의 트랜잭션 관리에 대해 설명해주세요.

 

 

JPA(Java Persistence API)는 자바에서 데이터베이스와의 상호작용을 단순화하고 객체 지향적으로 관리할 수 있는 API입니다. JPA의 트랜잭션 관리는 데이터의 일관성을 보장하며, 작업의 원자성(Atomicity)을 유지하는데 중요한 역할을 합니다.

트랜잭션은 하나의 작업 단위로, 이 작업들은 모두 성공하거나 모두 실패해야 합니다. 즉, 트랜잭션 내의 모든 변경은 모두 커밋되거나 롤백되어야 합니다.

ex. JPA에서 트랜잭션의 시작과 종료는 EntityTransaction 인터페이스의 begin() 및 commit() 메서드를 통해 수행됩니다. 롤백은 rollback() 메서드를 사용하여 수행합니다.

JPA 트랜잭션 관리는 이처럼 작업의 원자성을 보장하며, 이를 통해 데이터의 무결성과 일관성을 유지합니다. 또한, Spring Framework 함께 사용할 경우 @Transactional 어노테이션을 통해 선언적 트랜잭션 관리를 있습니다. 이를 통해 코드의 가독성을 높이고, 안전하게 트랜잭션을 관리할 있습니다.

 

더보기

JPA에서 트랜잭션이란, 여러 데이터베이스 작업들이 모두 성공하거나 모두 실패하도록 보장하는 하나의 작업 단위를 말합니다. 이런 트랜잭션을 사용하면 데이터의 정확성을 보장할 수 있어요.

예를 들어, 당신이 은행에서 돈을 송금한다고 생각해봅시다. 송금 과정은 크게 두 단계로 나눠집니다. 첫째, 당신의 계좌에서 돈을 빼는 것. 둘째, 받는 사람의 계좌에 돈을 더하는 것. 이 두 단계 중 하나라도 실패하면 큰 문제가 발생하겠죠. 따라서 이 두 단계는 하나의 트랜잭션으로 묶여야 합니다.

JPA는 이런 트랜잭션을 관리해줍니다. 코드로 보면, begin()을 통해 트랜잭션을 시작하고, 모든 작업이 성공적으로 끝나면 commit()을 통해 변경 사항을 데이터베이스에 반영합니다. 만약 중간에 어떤 문제가 발생하면 rollback()을 통해 모든 작업을 원래 상태로 돌려놓습니다.

이렇게 JPA 트랜잭션 관리를 통해 여러 작업을 하나로 묶고, 작업들이 모두 성공하거나 모두 실패하도록 보장할 있습니다. 이는 데이터의 정확성을 유지하는데 매우 중요합니다.

 

2023.05.19 - [Mockterview] - 더티체킹 (Dirty Checking)