Spring Data JPA - 영속성컨텍스트
영속성
영속성이란 영구적이라는 뜻입니다. 즉 Entity를 영구적으로 저장하는 것이 영속성컨텍스트입니다.
저는 처음에 이 말을 보고 "DB에 저장하면 영구적으로 저장되는거 아닌가?"라고 생각했습니다.
맞는 말입니다. 그런데 여기서 저장하는 곳은 DB가 아니라 영속성컨텍스트라는 곳입니다.
프로그램과 DB사이에 영속성 컨텍스트라는 곳이 있고 거기에 먼저 저장을 한뒤 DB에 저장되는 것이라고 생각하면 됩니다.
사용이유
1.캐시
일단 영속성 컨텍스트는 Cache의 기능과 유사합니다. 캐시는 서버에 직접 접근하지 않고 캐시에 먼저 접근해 요청 데이터가 캐시에 있으면 데이터를 꺼내오고 없으면 서버에 접근하는 방식을 사용합니다.
영속성 컨텍스트는 캐시와 유사하지만 방향만 반대라고 생각하시면 됩니다.
2.쓰기 지연
동작하는 쿼리문들이 한번씩 동작하는 것이 아닌 영속성컨텍스트에 저장하고 한번에 동작합니다.
SQL을 바로 보내지 않고 모아서 보낼 수 있습니다.
이점
그렇다면 이 기능을 사용해서 얻는 이점이 무엇일까요 DB에 바로 반영되는 게 좋은게 아닐까요
예를 들어 결제서비스를 생각해보면 결제는 사용자의 돈이 차감되고 판매자의 돈이 증가하는 두개의 동작입니다.
그런데 만약 오류가 발생해 사용자의 돈만 차감되고 판매자는 돈이 증가하지 않는 문제가 발생할 수 있습니다.
이 때 영속성 컨텍스트를 사용하면 DB에 반영되기 전에 두 개의 메소드가 문제가 생겼을 때 처리를 해 위의 문제를 사전에 막을 수 있습니다.
Entity Manager(EM)
영속성컨텍스트에서 가장 핵심적인 클래스는 EntityManager클래스는 하나의 영속성컨텍스트를 공유해서 사용합니다.
Entity의 동작과정을 살펴보면 DB나 사용자가 넘긴 데이터를 Entity로 만든후 EntityManager의 영속성컨텍스트가 관리하게 됩니다.
JPA 인터페이스의 여러 메소드들의 내부를 살펴보면 EntityManager의 메소드들이 들어가있는 것을 확인해 볼 수있습니다. EM(EntityManager)의 메소드들을 알고 기능을 학습하기 보다는 JPA에서 제공하는 메소드들에서 이미 포함이 되어있으므로 동작원리를 아는 것이 더 중요하다고 생각합니다
영속성에 대한 학습을 하지 않은채로 JPA를 사용하고 계신 분이라면 한번쯤 DB의 data와 조회한 data가
다른 경우를 경험해 보셨을 겁니다. 이 경우 영속성을 사용하신 겁니다 영속성 컨텍스트는 쉽게 말하면 여러 쿼리문들을 병합해서 한번에 DB에 반영시키는 역할을 합니다. 또한 DB에 접근하지 않고 데이터를 조회할 수 도있습니다.
DB와 영속성컨텍스트 동기화
1.flush()
EM의 .flush()메소드를 실행했을 때입니다 이 메소드의 기능자체가 영속성 컨텍스트의 내용을 DB에 반영시키는 것이기 때문에 의도적으로 사용해야합니다
2.트랜잭션이 종료
트랜잭션에 대해 모르신다면 간단하게 메소드나 쿼리들을 하나로 묶어주는 역할을 하신다고 생각하면됩니다. 예를 들어서 delete쿼리문과 insert쿼리문을 트랜잭션을 사용하면 하나의 쿼리문으로 사용해 쿼리문을 한번에 적용할 수 있습니다. 트랜잭션의 시작은 메소드의 시작을 의미하고, 트랜잭션의 종료는 commit을 한 시점입니다. 뒤의 트랜잭션 설명글에서 자세하게 설명하겠습니다
3.JPQL
복잡한 쿼리문을 사용했을 때 즉 JPQL을 사용했을 때입니다. JPQL은 JPA에서 지원하는 쿼리문입니다. 메소드식 쿼리문은 한계가 있기 때문에 쿼리문을 객체지향적으로 작성하는 문법입니다
위 3가지 경우에 동기화가 발생합니다.
Entity의 생명주기
사실 JPA를 한번쯤 공부해보시면 Entity의 생명주기라는 단어를 많이 들어보셨을 겁니다.
만약 모르셨다고 해도 JPA를 사용해보셨다면 자동으로 사용되었을 것입니다.
생명주기에는 4가지가 있습니다. 하지만 저는 생명주기라는 단어를 듣고 의미를 혼돈했기 때문에 저는 Entity의
4가지 종류라고 생각하는게 더 이해가 갔습니다
영속 - EM이 관리하고 있는 Entity(em.persist())
비영속-EM이 관리하고 있는 않는 Entity(단순 class)(new)
준영속- EM에서 관리되었지만 지금은 관리되지않는 Entity(em.detach())
삭제 - DB와 EM에서 삭제된 Entity(em.remove())
이 4가지로 분류됩니다. 보통 저희가 많이 사용하는 것은 당연히 영속인 Entity입니다.
사실 영속성 컨텍스트와 Entity의 생명주기 둘다 중요한 개념입니다 저는 이 두 개념이 중요한 이유가 트랜잭션을 위한 것이라고 생각합니다. 이 두 개념을 이용해 만든 기능이 트랜잭션이기 때문에 트랜잭션의 이해를 위해서 반드시 알아야 하기 때문입니다.