콘텐츠로 이동

2024 02 21

2024-02-21

Spring Batch + JPA (transactionManager)

참고: https://velog.io/@rainmaker007/spring-batch-multi-datasource-jpa-transactionManager-%EC%A0%95%EB%A6%AC 참고: https://chung-develop.tistory.com/146

  • TransactionManager?
    • 데이터베이스와 같은 외부 리소스 관리하는 역할
    • Job/Step에서 외부 리소스 (ex. DB) 사용 시, TransactionManager를 사용하여 데이터 정합성 유지
  • Spring Batch의 Transaction 처리
    • Job/Step Transaction 처리를 위해 TransactionManager 사용
      • Spring의 PlatformTransactionManager 인터페이스 구현한 객체 사용
    • 처리 순서
      1. Spring Batch... Job 실행 전 JobRepository를 통해 JobExecution 생성
      2. JobExecution은 PlatformTranscationManager를 사용해 트랜잭션 처리
  • PlatformTransactionManager 구현체 종류/특징
    1. DataSourceTransactionManager
      • DataSource를 이용한 트랜잭션 처리 위한 구현체
      • JDBC 사용하는 경우
      • 단순/쉬움
      • ORM(JPA)와 호환성 떨어짐
    2. JpaTransactionManager
      • JPA를 이용한 트랜잭션 처리 구현체
      • EntityManagerFactory 사용
      • JPA 구현체와 호환성 좋음
      • EntityManagerFactory를 사용하다보니, EMF 생성시점에 DataSource를 미리 설정할 것

Spring Batch + JPA (@Modifying)

  • 개요 (@Modifying)
    • @Query를 통해 작성된 INSERT/UPDATE/DELETE 쿼리에서 사용되는 어노테이션
    • jpaRepository에서 제공하는 메서드/메서드 네이밍으로 만들어진 쿼리에는 적용 X
    • 주로 벌크 연산과 같이 이용됨
    • JPA entity life-cycle 무시하고 실행됨
    • JPA에서 변경감지에 대한 처리를 생략하고 효율적인 실행이 가능함
    • @Modifying 안붙이면 SELECT 생성하는 쿼리인 줄로 알아! 읽기 전용 아니라고 알려줘야해!
  • example
    • 모든 유저의 나이를 늘려보자
      @Transactional
      @Modifying
      @Query("UPDATE User u SET u.age = u.age + 1")
      int incrementAllUserAges();
      
  • Bulk 연산
    • 다건의 UPDATE, DELETE 연산을 하나의 쿼리로
    • 영속성 컨텍스트는 벌크 연산을 통한 데이터 변경에 대해 알 길이 없기 때문에, 영속성 컨텍스트 <-> DB 싱크 안맞는 경우 있음
    • 따라서 @Modifying을 사용한다면 clearAutomatically=true로 설정해주자!
  • clearAutomatically
    • 기본은 false
    • @Modifying 직후 영속성 컨텍스트 1차 캐시 비워주기

Spring Batch + Insert (bulk insert)

  • JPA id identity를 쓰면 기본 채번 전략이 DB에서 가져오기에 N개 insert를 위해선 N번의 쿼리가 나가는 문제가 있었음.
  • Jdbc의 batchInsert를 활용하여 해결하자.