카테고리 없음
JPA test - 2
happyst
2024. 10. 30. 16:34
JPA의 성능 최적화 기능
1차 캐시와 동일성 (identity) 보장
- 같은 트랜잭션 안에서는 같은 엔티티를 반환함
EmployeeFindTest.java
package jpajava;
import domain.Employee;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
public class EmployeeFindTest {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpatest");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
System.out.println("TRANSACTION STARTED");
try {
System.out.println("비영속 상태");
System.out.println("DB에서 가져옴");
Employee emp1 = em.find(Employee.class, "202402");
System.out.println("employee.getEmpName() : " + emp1.getEmpName());
System.out.println("commit 전");
tx.commit();
System.out.println("commit 후");
System.out.println("1차 캐시에서 가져옴");
Employee emp2 = em.find(Employee.class, "202402");
System.out.println("employee.getEmpName() : " + emp2.getEmpName());
// 1차 캐시와 동일성(identity) 보장
System.out.println("emp1 == emp2 : " + (emp1 == emp2));
} catch (Exception e) {
tx.rollback();
System.out.println("TRANSACTION ROLLBACK");
System.out.println("[Error] " + e.getMessage());
} finally {
System.out.println("TRANSACTION ENDED");
}
}
}
실행 결과
트랜잭션을 지원하는 쓰기 지연 (Transactional Write Behind)
- 트랜잭션을 commit 할 때까지 INSERT SQL을 전송하지 않고 지연시킴
- commit하는 순간, 모아둔 INSERT SQL을 한번에 전송함 (Update, Delete도 마찬가지)
src/main/java/jpajava/EmployeeWriteBehind.java
package jpajava;
import domain.Employee;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
public class EmployeeWriteBehind {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpatest");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
System.out.println("TRANSACTION STARTED");
try {
Employee emp1 = new Employee("202403", "아이린", null, "2024-01-01", 600);
Employee emp2 = new Employee("202404", "슬기", null, "2024-01-01", 600);
Employee emp3 = new Employee("202405", "조이", null, "2024-01-01", 600);
em.persist(emp1);
em.persist(emp2);
em.persist(emp3);
System.out.println("commit 전");
tx.commit();
System.out.println("commit 후");
} catch (Exception e) {
tx.rollback();
System.out.println("TRANSACTION ROLLBACK");
System.out.println("[Error] " + e.getMessage());
} finally {
System.out.println("TRANSACTION ENDED");
}
}
}
실행 결과 - 쓰기 지연 적용 O
src/main/java/jpajava/DeptWriteBehind.java
package jpajava;
import domain.Department;
import domain.Employee;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
public class DeptWriteBehind {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpatest");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
System.out.println("TRANSACTION STARTED");
try {
Department dept1 = new Department();
dept1.setDeptName("AA");
Department dept2 = new Department();
dept2.setDeptName("BB");
Department dept3 = new Department();
dept3.setDeptName("CC");
em.persist(dept1);
System.out.println("dept1 생성");
em.persist(dept2);
System.out.println("dept2 생성");
em.persist(dept3);
System.out.println("dept3 생성");
System.out.println("commit 전");
tx.commit();
System.out.println("commit 후");
} catch (Exception e) {
tx.rollback();
System.out.println("TRANSACTION ROLLBACK");
System.out.println("[Error] " + e.getMessage());
} finally {
System.out.println("TRANSACTION ENDED");
}
}
}
실행 결과 - 쓰기 지연 적용 X
@GeneratedValue(strategy = GenerationType.IDENTITY)를 사용하면 쓰기 지연(write-behind)이 제대로 적용되지 않음
- IDENTITY 전략이 데이터베이스의 AUTO INCREMENT 기능을 통해 기본 키를 즉시 할당받기 때문에, 엔티티를 persist하는 순간 즉시 INSERT 쿼리를 실행해야만 기본 키 값을 가져올 수 있기 때문!!
- 쓰기 지연을 활용하려면 GenerationType.SEQUENCE나 GenerationType.TABLE 같은 다른 키 생성 전략을 사용해야 함