사용자 도구

사이트 도구


springframework:batch

문서의 이전 판입니다!


Spring Framework Batch

@EnableBatchProcessing

DefaultBatchConfigurer

  • 설정 중 일부를 Override하고자 한다면 DefaultBatchConfigurer 를 Configuration class에서 상속해서 메소드를 오버라이드 한다.
  • dataSource 오버라이드 예
    // 다른 configuration class 에서 DataSource 생성 - embedded 예제
    @Bean
    public DataSource batchDataSource() {
        return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2)
                .addScript("classpath:/org/springframework/batch/core/schema-h2.sql")
                .build();
    }
     
    @EnableBatchProcessing
    @Configuration
    public class BatchApplication extends DefaultBatchConfigurer {
        // dataSource 설정부분 override. transactionManager도 자동으로 생성함.
        @Autowired
        @Override
        public void setDataSource(@Qualifier("batchDataSource") DataSource batchDataSource) {
            super.setDataSource(batchDataSource);
        }
    }
  • dataSource 자체를 null로 지정하면 MapJobRepository로 DB없이 작동하게 만들어진다.
  • SpringBoot 에서 DefaultBatchConfigurer 사용시 TransactionManager 오작동 문제가 발생한다. SpringBoot와 SpringBatch 참고

JobRepository

  • org.springframework.batch.core.repository.support.JobRepositoryFactoryBeanSimpleJobRepository 생성
  • MapJobRepositoryFactoryBean 로 in memory Job Repository 생성 가능.
  • org.springframework.batch.core 패키지에 schema-*.sql 파일이 Batch Job Repository DB 스키마이다.
  • schema-mysql.sql의 경우
    • textlongtext
    • datetimedatetime(6)로 변경해서 실행할 것.

Migration

Transaction 설정

트랜잭션 매니저를 지정하지 않으면

TransactionManager를 지정하지 않으면 다음과 같은 오류가 발생한다.

java.lang.IllegalStateException: To use the default BatchConfigurer the context must contain precisely one DataSource, found X

트랜잭션 기본 설정 및 트랜잭션 없이 실행하기

TransactionManager 를 ResourcelessTransactionManager 로 지정하면 된다.

혹은 아래와 같이 propagation=“NEVER”로 지정한다.

<batch:job id="jobid">
    <batch:step id="step1">
        <batch:tasklet ref="taskletId" transaction-manager="transactionManager">
            <batch:transaction-attributes propagation="NEVER"/>
        </batch:tasklet>
    </batch:step>
</batch:job>

Java Config

  • Step 등을 생성할 때 @Value(“#{jobParameter[paramName]}” String param 형태로 Job Parameter를 받을 수 있다.
@Bean
@JobScope
public Step myStep(@Value("#{jobParameters[date]}" String date, 
    @Value("#{jobParameters[count]}") long count) {
    // ...
}

JobInstanceAlreadyCompleteException: A job instance already exists and is complete for parameters 오류 발생

jobBuilderFactory.get("myJobName")
            .start(step())
            . .....
            .incrementer(new RunIdIncrementer())
            .build();

RunIdIncrementer 사용시 기존 파라미터가 현재 파라미터 지정한 것을 덮어씀

/**
 * 파라미터를 복사하지 않는 RunIdIncrementer
 */
public class ParamCleanRunIdIncrementer implements JobParametersIncrementer {
    private static String RUN_ID_KEY = "run.id";
    private String key = RUN_ID_KEY;
 
    public void setKey(String key) { this.key = key; }
 
    @Override
    public JobParameters getNext(JobParameters parameters) {
        JobParameters params = (parameters == null) ? new JobParameters() : parameters;
        long id = params.getLong(key, 0L) + 1;
        return new JobParametersBuilder().addLong(key, id).toJobParameters(); // 이부분이 RunIdIncrementer와 다르다.
    }
}

Java Config Spring Bean 설정시 리턴 타입을 인터페이스가 아닌 구현 클래스로 지정할 것.

  • @StepScope 등을 사용하는 등 할 경우 리턴 타입을 ItemReader<X>, ItemWriter<Y> 처럼 인터페이스로 할 경우 프록시 객체가 생성되고 그로 인해서 instanceOf 를 사용하는 일부 코드들이 작동하지 않거나, annotation 기반의 listener 등이 동작하지 않는 문제를 일으킨다.
  • 따라서 Spring Batch 용 각 스텝별 Bean 을 생성해서 리턴할 때는 항상 구현 클래스를 리턴 타입으로 지정할 것.
  • 다음과 같은 WARN 을 볼 수도 있다.
o.s.b.c.l.AbstractListenerFactoryBean : org.springframework.batch.item.ItemReader is an interface. The implementing class will not be queried for annotation based listener configurations. If using @StepScope on a @Bean method, be sure to return the implementing class so listner annotations can be used.

Test

참고

springframework/batch.1560906336.txt.gz · 마지막으로 수정됨: 2019/06/19 10:05 저자 kwon37xi