[Spring] Persistence Context

thingzoo·2023년 6월 26일
0

Spring

목록 보기
24/54
post-thumbnail

Persistence Context

  • Persistence(영속성, 지속성)

    Persistence를 객체의 관점으로 해석해 보자면 ‘객체가 생명(객체가 유지되는 시간)이나 공간(객체의 위치)을 자유롭게 유지하고 이동할수 있는 객체의 성질’을 의미한다.

  • 영속성 컨텍스트는 쉽게 말해 Entity 객체를 효율적으로 쉽게 관리하기 위해 만들어진 공간


JPA는 효율적인 처리를 위해 영속성 컨텍스트에 Entity 객체들을 저장하여 관리하면서 DB와 소통

EntityManager

  • EntityManager: Entity를 관리하는 관리자
    • 영속성 컨텍스트에 접근하여 Entity 객체들을 조작
  • EntityManager를 사용해서 Entity를 저장/조회/수정/삭제

EntityManagerFactory

  • EntityManagerFactory: EntityManager를 생성

  • EntityManagerFactory는 일반적으로 DB 하나에 하나만 생성되어 애플리케이션이 동작하는 동안 사용

  • 사용하려면 DB에 대한 정보를 전달해야함

    • /resources/META-INF/

      • persistence.xml 파일에 정보 저장
      <?xml version="1.0" encoding="UTF-8"?>
      <persistence version="2.2"
                   xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd">
          <persistence-unit name="memo">
              <class>com.sparta.entity.Memo</class>
              <properties>
                  <property name="jakarta.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/>
                  <property name="jakarta.persistence.jdbc.user" value="root"/>
                  <property name="jakarta.persistence.jdbc.password" value="{비밀번호}"/>
                  <property name="jakarta.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/memo"/>
      
                  <property name="hibernate.hbm2ddl.auto" value="create" />
      
                  <property name="hibernate.show_sql" value="true"/>
                  <property name="hibernate.format_sql" value="true"/>
                  <property name="hibernate.use_sql_comments" value="true"/>
              </properties>
          </persistence-unit>
      </persistence>
EntityManagerFactory emf = Persistence.createEntityManagerFactory("memo"); // EntityManagerFactory 생성
EntityManager em = emf.createEntityManager(); // EntityManager 생성

JPA의 Transaction

Transaction

  • 트랜잭션: DB 데이터들의 무결성과 정합성을 유지하기 위한 하나의 논리적 개념
    • 쉽게 표현하자면 DB의 데이터들을 안전하게 관리하기 위해서 생겨난 개념
  • 가장 큰 특징은 여러 개의 SQL이 하나의 트랜잭션에 포함될 수 있다는 점
  • 이때, 모든 SQL이 성공적으로 수행이 되면 DB에 영구적으로 변경을 반영하지만 SQL 중 단 하나라도 실패한다면 모든 변경을 되돌린다!
START TRANSACTION; # 트랜잭션 시작

INSERT INTO memo (id, username, contents) VALUES (1, 'Robbie', 'Robbie Memo');
INSERT INTO memo (id, username, contents) VALUES (2, 'Robbert', 'Robbert Memo');
SELECT * FROM memo;

COMMIT; # 트랜잭션 커밋 -> 해야만 DB에 반영됨

SELECT * FROM memo;

JPA의 Transaction

JPA는 DB의 이러한 트랜잭션 개념을 사용하여 효율적으로 Entity를 관리하고 있다.

  • 위처럼 JPA에서도 영속성 컨텍스트로 관리하고 있는 변경이 발생한 객체들의 정보를 쓰기 지연 저장소에 전부 가지고 있다가 마지막에 SQL을 한번에 DB에 요청해 변경을 반영한다.

예시

@Test
@DisplayName("EntityTransaction 실패 테스트")
void test2() {
    EntityTransaction et = em.getTransaction(); // EntityManager 에서 EntityTransaction 을 가져옵니다.

    et.begin(); // 트랜잭션을 시작합니다.

    try { // DB 작업을 수행합니다.

        Memo memo = new Memo(); // 저장할 Entity 객체를 생성합니다.
        // memo.setId(1L); // 식별자 값을 넣어줍니다. // 넣어주면 저장 성공
        memo.setUsername("Robbert");
        memo.setContents("실패 케이스");

        em.persist(memo); // EntityManager 사용하여 memo 객체를 영속성 컨텍스트에 저장합니다.

        et.commit(); // 오류가 발생하지 않고 정상적으로 수행되었다면 commit 을 호출합니다.
        // commit 이 호출되면서 DB 에 수행한 DB 작업들이 반영됩니다.
    } catch (Exception ex) {
        System.out.println("식별자 값을 넣어주지 않아 오류가 발생했습니다.");
        ex.printStackTrace();
        et.rollback(); // DB 작업 중 오류 발생 시 rollback 을 호출합니다.
    } finally {
        em.close(); // 사용한 EntityManager 를 종료합니다.
    }

    emf.close(); // 사용한 EntityManagerFactory 를 종료합니다.
}
  • EntityTransaction et = em.getTransaction();
    • EntityTransaction을 가져와 트랜잭션 관리
  • et.begin();
    • 트랜잭션 시작
  • et.commit();
    • 트랜잭션의 작업들을 영구적으로 DB에 반영
  • et.rollback();
    • 오류가 발생했을 때 트랜잭션의 작업을 모두 취소하고, 이전 상태로 되돌림
profile
공부한 내용은 바로바로 기록하자!

0개의 댓글