따라서 영속성 컨텍스트란 직역하자면 데이터를 영구적으로 저장하는 환경 정도로 해석될 수 있습니다.
영속성 컨텍스트 란? entity를 영구 저장하는 환경입니다
DB에 있는 데이터를 SELECT 해서 영속성 컨텍스트에 넣는 것 : 영속화
데이터 베이스에 넣을때 save는 영속성 컨텍스트에 넣어서 insert하지만
saveFlush는 바로 insert문을 실행한다.
기본적으로 JPA는 객체지향 언어인 JAVA와 Database 사이의 패러다임 불일치를 해결하기 위해서 도입된 규약입니다.
1. 객체로 되어있는 Java의 코드를 바로 Database에 적용할 수 없습니다.
2. Database에 직접적으로 Update를 진행하게 되면 수정 중 오류가 발생하였을 때 데이터베이스의 정보가 원하는 방향으로 모두 수정이 이루어지지 않거나, Database의 정보들이 손상될 수 있습니다.
그래서 1번을 해결하기 위해서 JPA를 이용하여 Query로 java문을 번역한뒤 Database와 정보를 주고 받는 행위를 합니다.
그런데 이 JPA는 영속성 컨텍스트(Persistence Context)를 이용합니다.
엔티티를 영구 저장하는 환경이라는 뜻
아래의 코드와 같이 엔티티 매니저를 통해서 영속성 컨텍스트에 접근할 수 있다.
EntityManager entityManager = new EntityManager();
entityManager.persist(entity)
비영속(new/transient)
영속성 컨텍스트와 전혀 관계가 없는 새로운 상태
//객체를 생성한상태(비영속)
TestClass testClass = new TestClass();
testClass.setId("member1");
testClass.setUsername("회원1");
영속(managed)
영속성 컨텍스트에 관리되는 상태
//객체를 저장한 상태(영속)
entityManager.persist(testClass);
준영속(detached)
영속성 컨텍스트에 저장되었다가 분리된 상태
//영속성 컨텍스트에서분리, 준영속 상태
entityManager.detach(testClass);: 특정 엔티티만 준영속 상태로 전환
entityManager.clear();: 영속성 컨텍스트를 완전히 초기화
entityManager.close();: 영속성 컨텍스트를 종료
영속 -> 준영속
영속 상태의 엔티티가 영속성 컨텍스트에서 분리(detached)
영속성 컨텍스트가 제공하는 기능을 사용 못함
삭제(removed)
삭제된 상태
entityManager.remove(testClass);
즉 처음에 객체가 생성된 상태 -> 비영속
영속성 컨텍스트에 데이터가 저장된 상태 -> 영속
영속성 컨텍스트에 저장된 데이터가 분리된 상태 -> 준영속
마지막으로 삭제된 상태 -> 삭제
1차 캐시
반복가능한 일기(Reapeatable read) 등급의 트랜잭션 격리 수준을 데이터베이스가 아닌 어플리케이션 차원에서 제공합니다 격리성 레벨 4단계중 3단계 수준을 제공한다는 말입니다.
Member a = em.find(Member.calss, "member1" ); Member b = em.find(Member.calss, "member1" );
transaction이 시작되는 시점부터 끝나는 시점까지 저장소에 SQL을 모아 두고,
transaction이 종료되는 시점에 transaction.commit()이 호출됨과 동시에 모아둔 쿼리를 모두 보냅니다.
tx.begin(); : 트랜잭션 시작
.
em.persist(memberA);
em.persist(memberA);
// 여기까지는 insert sql을 데이터베이스에 보내지 않는다.
.
// 커밋하는 순간 데이터베이스에 insert sql을 보낸다.
tx.commit(); : 트랜잭션 커밋
em.find(entity)로 가져와 영속성 컨텍스트에 저장된 엔티티는 변경이 일어나면 자동으로 수정 됩니다 1차 캐시에 있는 스냅샷 필드와 비교하여 변경된 부분을 확인합니다
: flush()가 호출되는 시점에 Entity와 스냅샷을 전부 비교 후 변경이 된 것을 감지 ( Dirty Checking ) 한 후에 update 쿼리를 작성 후, update 쿼리를 보낸다.
// 엔티티 조회
Member memberA =em.find(Member.class, "memberA");
.
memberA.setUsernae("hello");
memberA.setAge(10);
.
// em.update(member); // update가 필요할 것처럼 보이지만 JPA가 알아서 비교해서 update 쿼리를 작성해준다.tx:commit(); : 커밋
: 영속성 컨텍스트의 변경 내용을 DB에 반영
플러시 발생
영속 컨텍스트를 플러시 하는 방법
영속성 컨텍스트를 비우지 않음
영속성 컨텍스트의 변경내용을 데이터베이스에 동기화
트랜잭션이라는 작업 단위가 중요 -> 커밋 직전에만 동기화하면 됨