<Spring Batch> 3. 배치 테이블 Embedded DB(H2)로 따로 관리하기
by BFine
출처 : http://www.yes24.com/Product/Goods/99422216
가. Embedded DB 사용 이유?
a. 서비스 DB에 배치 스키마가 생성되면 좀...그래
- 지난번 포스팅에서 DB가 여러대일 경우 JobRepository를 Custom 해서 사용한다고 공부했었다.
- 그리고 보통은 서비스 DB에 Batch 테이블을 쓰기엔 꺼려지기 때문에 별도로 관리하고 싶어진다..
- 또 배치 스키마를 위해서 DB를 새롭게 만들기엔 리소스가 아까우니 Embedded DB로 관리해보자
=> 책에는 없고 찾아도 잘 안나와서 직접 내부 보면서 커스터마이징 해야한다.
b. 특징
- 배치가 실행되고 종료될때 모든 배치 테이블 데이터는 휘발성이 되기 때문에 유의하자
=> 추가적으로 배치 테이블의 데이터를 직접 콘솔 확인이 어려울 수 있다.
나. 예제 코드
a. DataSource 분리
- 여러 DataSource 설정하는 방법은 아래에 잘정리되어있다.
=> https://www.baeldung.com/spring-data-jpa-multiple-databases
- 서비스 DB 하나만 있고 Embedded DB 사용해도 DataSource 분리가 필요하다.
=> 서비스 DB는 따로 Config를 만들고 요거를 @Primary 처리한 기준으로 예제를 구현했다.
b. DefalutBatchConfigurer
- 배치가 로딩되면 DefalutBatchConfigurer에서 가장 처음 실행되는 메서드가 .setDataSource 이다.
=> 코드를 보면 알수있듯이 DataSource는 한번 설정되면 추후에 변경할 수 없도록 설정 되어있다.
- 이후에 실행되는 메서드는 .initialize 이다 @PostConstruct로 보아 객체생성이후에 설정하는 것으로 보인다.
- 내용을 살펴보면 DataSource가 없는 경우에는 배치 Status 저장소로 Map을 사용한다는 것을 알 수 있다.
=> 이글을 쓰면서 MapJobExploreFactoryBean 클래스를 보니 v5 버전 부터 Deprecated 된다고 쓰여있다..
=> in-memory database 를 사용하자 (local 테스트할때는 Map 더 좋을 것 같은데..)
Deprecated v4.3 in favor or using the JobRepositoryFactoryBean with an in-memory database.
c. Custom Config 구현하기
- 책에는 위의 createXXX 를 커스텀하라고 되어있는데 코드를 보니 굳이 할필요 없다는 생각이 들었다.
- 단순하게 .setDataSource 부분만 Override 하면 더 간단하고 상속간 DataSource 불일치도 없어서 좋다.
- .getTransationManager 는 설정할필요없지만 WARN 로그 나오지 않게 하기 위해 추가했다.
- 주의할점은 .setDataSource 에 @Autowird 부분까지 가져와야 정상적으로 적용된다.
@RequiredArgsConstructor
@Configuration
public class CustomConfig extends DefaultBatchConfigurer {
@Bean
public DataSource embeddedDataSource(){
EmbeddedDatabaseBuilder embeddedDatabaseBuilder
= new EmbeddedDatabaseBuilder();
return embeddedDatabaseBuilder.setType(EmbeddedDatabaseType.H2)
.addScript("/org/springframework/batch/core/schema-h2.sql")
.build();
}
@Override
@Autowired(required = false)
public void setDataSource(DataSource dataSource) {
super.setDataSource(embeddedDataSource());
}
@Override
public PlatformTransactionManager getTransactionManager() {
return new DataSourceTransactionManager(embeddedDataSource());
}
}
- addScript를 추가한 이유는 initialize-schema: always 설정하면 @Primay DataSource만 적용되어
원하지 않는 서비스 DB에만 생겨서 이부분을 제거하고 H2 빌드 시에 배치 스키마를 생성하도록 했다.
=> org.h2.jdbc.JdbcSQLSyntaxErrorException: Table "BATCH_JOB_INSTANCE" not found 방지
- schema sql은 bath-core 라이브러리 안에 맨아래에 종류별로 포함되어있다.
다. 테스트
a. Job 설정
@RequiredArgsConstructor
@Configuration
public class BatchConfig {
private final JobBuilderFactory jobBuilderFactory;
private final StepBuilderFactory stepBuilderFactory;
private final JobExplorer jobExplorer;
@Bean
public Job job(Step step){
return jobBuilderFactory.get("Custom Test")
.start(step)
.build();
}
@Bean
public Step step(){
return stepBuilderFactory.get("Custom Step")
.tasklet((e,c)->{
Long jobInstanceId = c.getStepContext().getJobInstanceId();
JobInstance jobInstance = jobExplorer.getJobInstance(jobInstanceId);
System.out.println("JobName : "+jobInstance.getJobName()+"
, version : "+jobInstance.getVersion());
return RepeatStatus.FINISHED;
})
.build();
}
}
- 간단하게 Step안에서 JobExplorer를 통해 JobInstance를 조회하여 출력하도록 구현하였다.
- 디버깅해서 JobExplorer를 따라가 보면 JdbcTemplate로 query 하는것을 볼 수 있다.
b. 실행 결과
- 정상적으로 실행이 되었고 jdbc:h2:mem:testdb 로 embedded database 가 실행되었다는 로그를 볼 수 있다.
- H2 콘솔로 접속해보면 정상적으로 배치 Status가 저장되는 것을 볼 수 있다.
'공부 > Spring Batch' 카테고리의 다른 글
<Spring Batch> 5. ItemProcessor, ItemWriter (0) | 2021.10.03 |
---|---|
<Spring Batch> 4. Chunk 기반 배치, ItemReader (0) | 2021.10.02 |
<Spring Batch> 2. JobRepository, Config Customizing (0) | 2021.09.22 |
<Spring Batch> 1. JobParameters, ExecutionContext (0) | 2021.09.21 |
<Spring Batch> 0. 스프링 배치란? (2) | 2021.09.19 |
블로그의 정보
57개월 BackEnd
BFine