본문 바로가기
Spring

[TIL] 231116 Spring | 영속성컨텍스트 JPA 트렌젝션 EntityManager

by studymode 2023. 11. 16.

영속성 컨텍스트

- Entity객체를 관리하기 위해 만들어진 공간

- Entity는 Entity Manager에 의해 관리된다

 

 

 

JPA

- 개발자들이 SQL을 사용하지 않아도 DB와 소통할 수 있게 해줌

- JPA는 영속성 컨텍스트를 통해 Entity객체를 관리하면서 DB와 소통함

 

 

 

Entity Manger

- Entity를 관리함

- EntityManagerFactory를 통해 엔티티매니저 생성

- /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");
EntityManager em = emf.createEntityManager();

 

 

트랜잭션 

(한국어로 거래 라는 뜻)

- 여러 SQL을 하나에 트랜젝션에 담아서 DB를 안전하게 관리

- COMMIT; 으로 한번에 DB에 저장

 

 

 

JPA 트랜잭션

- 여러 Entity를 하나에 트랜젝션에 포함시겨 관리

 

- 영속성 컨텍스트로 관리하고 있는 객체에 변경이 발생하면 쓰기지연저장소 (Action Queue)에 가지고 있다가

마지막에 SQL을 한번에 DB에 요청

 

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

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

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

        Memo memo = new Memo(); // 저장할 Entity 객체를 생성합니다.
        memo.setId(1L); // 식별자 값을 넣어줍니다.
        memo.setUsername("Robbie");
        memo.setContents("영속성 컨텍스트와 트랜잭션 이해하기");

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

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

    emf.close(); // 사용한 EntityManagerFactory 를 종료합니다.
}

                                                 

코드 기능
EntityTransaction et = em.getTransaction(); 엔티티 트랜젝션 가져오기
et.begin();     트랜젝션 시작
em.persist(객체); EntityManager을 사용하여 객체를 영속석 컨텍스트에 저장
et.commit(); commit으로 DB저장
em.close(); EntityManager 종료
emf.close(); EntityManagerFactory 종료

 

 

 

 

영속성 컨텍스트의 기능

- Entity 객체를 효율적으로 관리하기 위한 공간

 

  1. 1 캐시 기능
    • Map자료구조 => key는 @Id, value는 Entity객체
    • em.find에서 key로 찾을 수 있음
    • em.remove(객체)로 삭제할 객체를 deleted상태로 만든 후 커밋하여 DB에 삭제 요청
  2. 쓰기지연저장소 (Action Queue)
    • 쓰기지연저장소에 저장해뒀다 커밋할때 한번에 디비에 반영
    • em.flush() 쓰기지연저장소에 있던게 저장됨
    • et.commit하면 자동으로 flush 실행됨
  3. Dirty checking (변경감지
    • JPA에는 update기능은 없음
    • 변경할 데이터가 있으면 조회-변경할 데이터 입력-커밋/flush로 디비에 저장
    • em.find(key); 변경할 엔티티 키 불러오기
    • setUsername(“~~”) 같은 메소드로 다시 설정
    • 커밋(flush)하면 전 정보와 비교해서 다르면 새로운 정보를 저장함

 

((모든 기능은 트렌젝션환경이 걸려잇어야함!!!))