240927 내일배움캠프 백엔드 Java 6기 TIL : Thread-safe

박대현·2024년 9월 27일
0

EntityManagerFactory와 EntityManager 개념에서 thread-safety(쓰레드 안전성)가 중요한 이유는 Java 에서 데이터베이스에 접근하는 방식과 관련이 깊습니다.

1. 쓰레드 안전성(Thread Safety)

쓰레드 안전성은 여러 쓰레드가 동시에 객체에 접근하더라도 객체의 상태가 올바르게 유지되는 것을 의미합니다. 쓰레드 안전성이 없는 객체를 여러 쓰레드에서 동시에 사용할 경우 데이터 무결성이 깨질 수 있습니다.

2. EntityManagerFactory와 EntityManager 개념

  • EntityManagerFactory: 데이터베이스와 상호작용할 수 있는 EntityManager 객체를 생성하는 팩토리 클래스입니다. 보통 애플리케이션에서 하나만 생성하여 공유됩니다. thread-safe(쓰레드 안전)합니다.
  • EntityManager: 실제로 데이터베이스에 대한 CRUD 작업(삽입, 조회, 업데이트, 삭제)을 수행하는 객체입니다. thread-safe하지 않아, 즉 한 번에 하나의 쓰레드에서만 사용해야 합니다. 사용후 반드시 닫아야 합니다.(close() 메소드)

3. 쓰레드 안전성을 바탕으로 EntityManager 사용하기

EntityManager는 쓰레드마다 개별적으로 사용해야 하기 때문에, 일반적으로 아래와 같은 방식으로 사용합니다.

EntityManagerFactory emf = Persistence.createEntityManagerFactory("persistence-unit");
EntityManager em = emf.createEntityManager();

try {
    em.getTransaction().begin();
    // 데이터베이스 연산 수행
    em.getTransaction().commit();
} catch (Exception e) {
    em.getTransaction().rollback();
} finally {
    em.close();  // EntityManager는 사용 후 반드시 닫아야 합니다.
}

위 코드는 각 쓰레드가 독립된 EntityManager를 가져와 데이터베이스 작업을 수행한 후, 작업이 끝나면 close()로 자원을 해제하는 방식입니다.

4. 쓰레드 풀(Thread Pool) 환경에서의 처리

Spring 프레임워크나 Java 환경에서는 트랜잭션 관리를 담당하는 기능이 내장되어 있어서, 개발자가 직접 트랜잭션을 관리하지 않아도 됩니다. Spring의 @Transactional을 사용하면 쓰레드마다 적절하게 EntityManager를 할당해줍니다.

@Service
public class MyService {

    @PersistenceContext
    private EntityManager em;

    @Transactional
    public void someDatabaseOperation() {
        // EntityManager는 트랜잭션 범위 내에서 안전하게 사용됩니다.
        em.persist(newEntity);
    }
}

요약

  • EntityManagerFactorythread-safe하므로 여러 쓰레드에서 안전하게 공유할 수 있습니다.
  • EntityManagerthread-safe하지 않으므로, 쓰레드마다 독립적으로 생성 및 사용해야 합니다.
  • Spring에서는 @Transactional 어노테이션을 사용하여 쓰레드 안전한 EntityManager 사용을 자동으로 처리할 수 있습니다.

0개의 댓글