[JPA]영속성 컨텍스트

무지성개발자·2023년 12월 20일
0

영속성 컨텍스트

영속성 컨텍스트는 DB와 어플리캐이션 서버의 중간에서 엔티티를 저장하고 관리하는 역할을 하는 가상의 저장 공간을 말한다. 영속성 컨텍스트는 엔티티 매니저(EntityManager) 접근이 가능하다.

영속성 컨텍스트 라이프사이클

비영속 상태(New)

비영속은 엔티티는 생성을 했지만 아직 영속성 컨텍스트에 등록되지 않은 상태로 영속성 컨텍스트에서 관리되지 않는 상태다.

영속 상태(Managed)

영속 상태는 엔티티 매니저를 통해 영속성 컨텍스트에 등록 된 상태로 엔티티가 영속성 컨텍스트에서 관리되는 상태를 말한다. persist()로 엔티티를 영속 상태로 만들어 줄 수 있다.

  • 영속 상태의 이점
    • 1차 캐시
      • DB에서 값을 찾기 전에 영속 컨텍스트에서 먼저 값을 찾음.
    • 동일성 보장(동등성x)
      • 영속성 컨텍스트에서 할당한 값은 언제나 동일한 값임.
    • 쓰기지연
      • 엔티티의 새로운 값을 추가하면 바로 DB에 저장하는 것이 아니라 영속성 컨텍스트에 먼저 추가 후 나중에 DB에 반영.
    • 변경감지
      • 영속 상태의 엔티티의 값이 변경되면 알아서 update 쿼리문 실행.

준영속 상태(Detached)

준영속 상태는 영속성 상태의 엔티티가 영속성 컨텍스트에서 분리된 상태를 말한다. detach(), clear(), close() 명령어로 영속성 컨텍스트에서 엔티티를 분리할 수 있다. 준영속 상태의 엔티티는 영속 상태의 이점을 누릴 수 없다.

준영속 상태의 엔티티를 다시 영속 상태로 만들려면 merge()명령어를 사용하면 된다.

삭제 상태(Removed)

삭제 상태는 영속컨 텍스트에서 엔티티를 삭제했지만 아직 DB에는 반영 되지 않은 상태를 말한다. remove() 명령어로 엔티티를 삭제할 수 있다.

영속성 컨텍스트는 쓰레드 세이프한가?

영속성 컨텍스트는 쓰레드 세이프 하지 않다. 때문에 영속성 컨텍스트는 쓰레드간에 공유가 되면 같은 엔티티에 접근할 때 정합성의 문제가 생길 수 있다.

하지만 스프링에서 영속성 컨텍스트는 쓰레드 세이프 하다. 이유는 스프링은 엔티티 매니저를 프록시로 생성하면서 쓰레드간 동시접근을 막고있기 때문이다.

   public static EntityManager createSharedEntityManager(EntityManagerFactory emf, @Nullable Map<?, ?> properties, boolean synchronizedWithTransaction, Class<?>... entityManagerInterfaces) {
        ClassLoader cl = null;
        if (emf instanceof EntityManagerFactoryInfo emfInfo) {
            cl = emfInfo.getBeanClassLoader();
        }

        Class<?>[] ifcs = new Class[entityManagerInterfaces.length + 1];
        System.arraycopy(entityManagerInterfaces, 0, ifcs, 0, entityManagerInterfaces.length);
        ifcs[entityManagerInterfaces.length] = EntityManagerProxy.class;
        return (EntityManager)Proxy.newProxyInstance(cl != null ? cl : SharedEntityManagerCreator.class.getClassLoader(), ifcs, new SharedEntityManagerInvocationHandler(emf, properties, synchronizedWithTransaction));
    }

위 코드는 SharedEntityManagerCreator클래스에서 확인 할 수 있으며 마지막 return 부분을 보면 다이나믹 프록시를 사용하고 매개변수로 스레드세이프를 체크하는 기능이 들어가는 걸 확인 할 수있다.


profile
no-intelli 개발자 입니다. 그래도 intellij는 씁니다.

0개의 댓글