DeJa
Techvu
DeJa
전체 방문자
51,021
오늘
19
어제
54
  • Techvu (60)
    • DesignPatterns (3)
      • 생성 (0)
      • 구조 (1)
      • 행동 (2)
    • Refactoring (0)
    • DataStructures (0)
    • Algorithms (24)
      • 기본 지식 (12)
      • 문제 풀이 (12)
    • OOP (0)
    • TDD (2)
    • DDD (0)
    • Programming Languages (9)
      • Java (9)
      • Kotlin (0)
    • Spring (1)
    • JPA (7)
    • Web (1)
      • 기본 지식 (1)
      • 실무 경험 (0)
    • CS (12)
      • Network (1)
      • OS (8)
      • DataBase (3)
      • Server (0)
    • Git (1)
    • Conferences (0)

블로그 메뉴

  • 홈
  • 태그
  • 미디어로그
  • 위치로그
  • 방명록

공지사항

  • Study
  • GitHub
  • Medium Blog

인기 글

  • 스키마(Schema)
    2022.01.08
    스키마(Schema)
  • 자바 버전별 역사 및 특징
    2022.01.12
    자바 버전별 역사 및 특징
  • 깃허브 사용 방법
    2021.12.15
    깃허브 사용 방법
  • 동시성 이슈(Concurrency Issue)
    2022.03.20
    동시성 이슈(Concurrency Issue)
  • JPA 는 과연 1차 캐시를 통해서 Repeatable R⋯
    2021.12.27
    JPA 는 과연 1차 캐시를 통해서 Repeatable R⋯

태그

  • Spring
  • DATABASE
  • network
  • 디자인패턴
  • web
  • OS
  • JPA
  • java
  • TDD
  • 알고리즘
  • CS

최근 댓글

  • 글 잘읽고 가요.
    아이폰
  • 컴파일러자체에서 꼬리재귀를 지원하지 않으니 static으로⋯
    aaa
  • 압도적 감사
    ㅇㅇㅇ

최근 글

  • Write a test code right now
    2022.03.24
    Write a test code right now
  • 동시성 이슈(Concurrency Issue)
    2022.03.20
    동시성 이슈(Concurrency Issue)
  • POJO, JavaBean, Entity, VO, DTO
    2022.02.08
    POJO, JavaBean, Entity, VO, DTO
  • TDD with Agile
    2022.02.05
    TDD with Agile
  • Java Stream 기초
    2022.01.23
    Java Stream 기초

티스토리

hELLO · Designed By 정상우.
DeJa

Techvu

EntityManager 를 쓰레드간 공유하면 안되는 이유
JPA

EntityManager 를 쓰레드간 공유하면 안되는 이유

2021. 12. 28. 18:54
728x90

EntityManager 를 쓰레드간 공유하면 안되는 이유

EntityManager 를 쓰레드간 공유하면 안되는 이유에 대해서 배워보자.

Test

테스트할 주제는 EntityManager 를 하나로 사용하고 있는 상태에서 서로 다른 Thread 두 개를 생성하고 ThreadA 는 데이터베이스에서 데이터를 읽어와 1차 캐시에 저장하는 역할을 하고, ThreadB 에서는 데이터 조회와, 데이터 수정 작업을 담당하게끔 코드를 짜서 테스트할 것이다.

포인트는 ThreadB 에서 데이터를 읽어올 때, 1차 캐시에 존재하는 데이터를 읽어올지, 데이터베이스로부터 값을 조회해올지가 포인트다.

@DisplayName("1차 캐시 테스트")
@SpringBootTest
class FirstCacheTest {

    @Value("${persistence.unitname}")
    private String persistenceUnitName;

    @DisplayName("EntityManger 를 스레드간 공유하면 1차 캐시의 내용을 공유하는지 테스트")
    @Test
    void oneEntityManagerAndTwoThreadIsSharedFirstCache() throws Exception {
        // given
        EntityManagerFactory emf = Persistence.createEntityManagerFactory(persistenceUnitName);
        insertDummyData(emf);

        // when
        EntityManager em = emf.createEntityManager();
        EntityTransaction tx = em.getTransaction();

        /*
         * 서로 다른 스레드 두개 생성 : 클라이언트의 요청이 두 개 들어왔다고 가정
         * threadA -> threadB 순서로 한다고 가정
         */
        tx.begin();
        Thread threadA = new Thread(() -> {
            // 데이터베이스에서 조회하여 1차 캐시에 내용 저장
            Member member = em.find(Member.class, 1L);
        });

        Thread threadB = new Thread(() -> {
            // 여기서 1차 캐시에서 조회되는지 데이터베이스에서 조회되는지 확인
            Member member = em.find(Member.class, 1L);
            member.setAge(29);
            em.persist(member);
        });

        // 2초 뒤에 스레드 B 시작
        threadA.start();
        Thread.sleep(2000);
        threadB.start();

        // 3초 뒤에 커밋하고 종료
        Thread.sleep(3000);
        tx.commit();
        em.close();
        emf.close();
    }

    @DisplayName("더미 데이터 삽입")
    private void insertDummyData(EntityManagerFactory emf) {
        EntityManager em = emf.createEntityManager();
        EntityTransaction tx = em.getTransaction();

        tx.begin();

        Member member = new Member();
        member.setUsername("JungHo");
        member.setAge(28);
        em.persist(member);
        tx.commit();

        em.close();
    }
}

테스트 결과 ThreadA 는 예상하는 것처럼 동작하고, ThreadB 에서 같은 EntityManager 를 사용하고 있어서, ThreadA 에서 읽기 처리 후 1차 캐시에 저장한 데이터를 ThreadB 에서도 1차 캐시를 통해 데이터를 가져오고 값을 바꿀수 있게 되었다.

따라서, EntityManager 를 쓰레드간 공유하게 되면 심각한 데이터 오류, 정합성 문제가 발생할 것이다.

728x90
저작자표시 비영리 동일조건
  • 카카오스토리
  • 트위터
  • 페이스북

'JPA' 카테고리의 다른 글

다양한 연관관계 매핑과 설정에 따른 트레이드 오프  (0) 2021.12.31
테이블과 컬럼에 대한 명세를 엔티티에 자세하게 적는것이 좋은지?  (0) 2021.12.29
AllocationSize 를 통한 성능 최적화  (0) 2021.12.28
기본키 매핑 전략에 따른 INSERT QUERY 실행 시점  (0) 2021.12.28
JPA 는 과연 1차 캐시를 통해서 Repeatable Read 를 지원할까?  (0) 2021.12.27
    'JPA' 카테고리의 다른 글
    • 테이블과 컬럼에 대한 명세를 엔티티에 자세하게 적는것이 좋은지?
    • AllocationSize 를 통한 성능 최적화
    • 기본키 매핑 전략에 따른 INSERT QUERY 실행 시점
    • JPA 는 과연 1차 캐시를 통해서 Repeatable Read 를 지원할까?
    JPA, Spring
    DeJa
    DeJa
    Tech Blog
    댓글쓰기
    기본키 매핑 전략에 따른 INSERT QUERY 실행 시점
    다음 글
    기본키 매핑 전략에 따른 INSERT QUERY 실행 시점
    JPA 는 과연 1차 캐시를 통해서 Repeatable Read 를 지원할까?
    이전 글
    JPA 는 과연 1차 캐시를 통해서 Repeatable Read 를 지원할까?

    티스토리툴바