
Spring Batch 를 개발 할 일이 생겼다.
그런데 DB 가 티베로여서 환경을 구축하는데 애먹었다 ㅠㅠ
힘들었던 과정이 있었기 때문에 블로그로 기록하려고 한다.
Spring Batch + Tibero DB 연동
일단 티베로인 경우에는 Spring Batch 에서 지원하지 않는 databaseType 이기 때문에 SQL 변형이 충분히 유사하면 지원되는 유형 중 하나를 사용하여 한다. 지원되는 유형으로 재설정 하기 위해서는 JobRepositoryFactoryBean 으로 해줘야 하며 아래 코드로 설명하도록 하겠다.
※ Spring Batch 에서 지원되는 데이터베이스 타입 : DERBY, DB2, DB2ZOS, HSQL, SQLSERVER, MYSQL, ORACLE, POSTGRES, SYBASE, H2
티베로와 같은 비표준 데이터베이스 유형인 경우, 왜 재설정 해줘야 하는지 와 관련된 설명은 아래 링크 참고 해주길 바란다.
https://www.egovframe.go.kr/wiki/doku.php?id=egovframework:rte2:brte:batch_core:job_repository
egovframework:rte2:brte:batch_core:job_repository [eGovFrame]
JobRepository는 배치 작업 중의 정보를 저장하는 역할을 한다. 어떠한 Job이 언제 수행되었고, 언제 끝났으며, 몇 번이 실행되었고 실행에 대한 결과가 어떤지 등의 배치 작업의 수행과 관련된 모든
www.egovframe.go.kr
Spring Batch - Reference Documentation
If a group of Steps share similar configurations, then it may be helpful to define a “parent” Step from which the concrete Steps may inherit properties. Similar to class inheritance in Java, the “child” Step combines its elements and attributes wit
docs.spring.io
1. pom.xml 설정
<!-- JDBC -->
<dependency>
<groupId>[tibero6-jdbc.jar 파일 저장 경로]</groupId>
<artifactId>tibero6</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
본인은 tibero가 저장되어 있는원격저장소의 경로를 지정해 주었는데, 따로 저장소가 없는 경우에는 tibero6-jdbc 를 다운 받아 로컬 경로를 지정하면 될것이다.
로컬 경로를 지정하는 방식에 대해 자세히 알고 싶은 경우 더보기를 눌러 해당 블로그를 참고해주세요~
2. application.properties 설정
spring.batch.jbdb.initialize-schema=never
로 설정해야 한다.
자세한 설명은 더보기를 눌러주세요~
spring.batch.jbdb.initialize-schema 설정은 스키마 생성을 자동생성 또는 수동생성 할지와 관련된 옵션이다.
Oracle 인 경우, pring.batch.jbdb.initialize-schema=always 로 설정해 두어도 정상적으로 연결이 되었으나, 티베로인 경우에는 never 로 꼭 설정해줘야 정상적으로 연결이 되었다.. ㅠㅠ
본인은 아래 블로그를 참고하였음.
https://hanseom.tistory.com/183
03. 메타데이터 스키마(Meta-Data Schema)
스프링 배치의 실행 및 관리를 위한 목적으로 여러 도메인들(Job, Step, JobParameters...)의 정보들을 저장, 업데이트 및 조회할 수 있는 스키마를 제공합니다. 과거, 현재의 실행에 대한 세세한 정보,
hanseom.tistory.com
※ 참고 ※
ALWAYS: 스크립트를 항상 실행합니다. RDBMS 설정이 되어 있을 경우 내장 DB보다 우선적으로 실행됩니다.
EMBEDDED: 내장 DB일 때만 실행되며 스키마가 자동 생성됩니다. (기본값)
NEVER: 스크립트를 항상 실행하지 않습니다. 운영에서 수동으로 스크립트 생성 후 설정하는 것을 권장합니다. 내장 DB일 경우 스크립트가 생성이 안되기 때문에 오류가 발생합니다.
3. DB 설정
import javax.sql.DataSource;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
@Configuration
public class SpringBatchDataSourceConfiguration {
// 비즈니스 DB 정보
@Bean
public DataSourceProperties batchDataSourceProperties() {
DataSourceProperties dataSource = new DataSourceProperties();
dataSource.setDriverClassName("비즈니스 DB driver-class-name");
dataSource.setUrl("비즈니스 DB url");
dataSource.setUsername("비즈니스 DB user-name");
dataSource.setPassword("비즈니스 DB password");
return dataSource;
}
@Bean
public DataSource tiberoDataSource() {
return batchDataSourceProperties().initializeDataSourceBuilder().build();
}
}
환경에 맞게 DB 정보를 설정해 주면 된다.
4. JobRepositryFactoryBean DB유형 재설정
1~3번 까지만 설정해 주면 아래와 같은 오류가 발생 한다.
Caused by: java.lang.IllegalStateException: Unable to initialize Spring Batch
at org.springframework.boot.autoconfigure.batch.BasicBatchConfigurer.initialize(BasicBatchConfigurer.java:107)
at org.springframework.boot.autoconfigure.batch.BasicBatchConfigurer.afterPropertiesSet(BasicBatchConfigurer.java:96)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800)
... 33 common frames omitted
Caused by: java.lang.IllegalArgumentException: DatabaseType not found for product name: [Tibero]
at org.springframework.batch.support.DatabaseType.fromProductName(DatabaseType.java:84)
at org.springframework.batch.support.DatabaseType.fromMetaData(DatabaseType.java:123)
at org.springframework.batch.core.repository.support.JobRepositoryFactoryBean.afterPropertiesSet(JobRepositoryFactoryBean.java:183)
at org.springframework.boot.autoconfigure.batch.BasicBatchConfigurer.createJobRepository(BasicBatchConfigurer.java:134)
at org.springframework.boot.autoconfigure.batch.BasicBatchConfigurer.initialize(BasicBatchConfigurer.java:102)
... 36 common frames omitted
해당 오류를 해결하기 위해서, JobRepository 를 설정해줘야 한다.
import javax.sql.DataSource;
import org.springframework.batch.core.configuration.annotation.DefaultBatchConfigurer;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager;
@Configuration
public class TiberoBatchConfiguration extends DefaultBatchConfigurer{
@Autowired
@Qualifier("tiberoDataSource")
private DataSource tiberoDataSource;
@Autowired
private PlatformTransactionManager transactionManager;
@Autowired
private ApplicationContext applicationContext;
public TiberoBatchConfiguration() {
super();
}
public TiberoBatchConfiguration(DataSource dataSource) {
super(dataSource);
}
@Override
protected JobRepository createJobRepository() throws Exception{
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
factory.setDataSource(tiberoDataSource);
factory.setDatabaseType("ORACLE"); // Tibero Db 는 지원하지 않는 DB 기 때문에 지원되는 DB로 set
factory.setTablePrefix("원하는 스키마 설정");
factory.setTransactionManager(transactionManager);
factory.afterPropertiesSet();
return factory.getObject();
}
}
-- 여기서부터 엄청 고생했다 ㅠㅠㅠㅠ
org.springframework.dao.DataAccessResourceFailureException: Could not obtain sequence value; nested exception is java.sql.SQLException: JDBC-8034:Specified sequence was not found.
at line 1, column 9 of null:
select [지정한 Schema].BATCH_JOB_SEQ.nextval from dual
1~4 번까지 설정을 해주면 DB 연결이 될줄 알았는데 계속해서 오류가 발생했다.
오류의 내용은 sequence 를 찾을 수 없다는 오류 이고
검색하면 나오는 해결책은 전부다 DB 설정 + JobRepository 로 데이터베이스 유형을 재설정 하라는 대답과 H2 를 설정하여 Metatable 없이 Spring Batch 를 구현할 수 있다는 대답 밖에 없었다...
주변에 Spring Batch 에 대해 알고 있는 개발자 + 실무자 가 없어 진짜 일주일 정도 고생을 했으나 결론은.. MetaTable 때문이었다..
http://blog.devjoshua.me/2021/03/14/spring-boot-without-metadata-table/
[Spring Batch] 메타 테이블 없이 스프링 배치 구성하기
QA에서 개발로 전직한 주니어 개발자의 블로그입니다
blog.devjoshua.me
해당 블로그를 참고하면 Spring Batch 에서 메타테이블이 필요한 이유에 대해 설명해주고 있으며, 메타테이블 없이 Spring Batch 를 구성할 수 있는 방법도 알려준다.
검색하면서 확실하게 '메타테이블 이 없기 때문에 발생하는 오류이기 때문에 메타테이블을 생성해라!' 라는 말이 없어서 엄청 고생을 했던거 같다. Spring Batch 에 대해 확실하게 알고라도 있으면 금방 해결했을텐대
DB 테이블을 쉽게 생성할 수 없는 환경이었기 때문에 꾸역꾸역 메타테이블 없이 하려다 보니 돌아갔던거 같다.
결론적으로는 운영 시에는 필수적으로 메타테이블은 필요한 것이고, 메타테이블을 생성하여 오류를 해결하였다....
만약 로컬에서만 Spring Batch 를 돌려야 하는 상황이라면 H2 등 가상의 테이블을 활용하여 테스트 할 수 있으나, 더보기 안의 블로그에서 설명해주듯이 운영 시에는 메타테이블이 필요하다.
5. 최종
import javax.sql.DataSource;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
@Configuration
public class SpringBatchDataSourceConfiguration {
// spring batch MetaTable DB 정보
@Bean
public DataSourceProperties tiberoBatchMetaTableProperties() {
DataSourceProperties dataSource = new DataSourceProperties();
dataSource.setDriverClassName("비즈니스 DB driver-class-name");
dataSource.setUrl("비즈니스 DB url");
dataSource.setUsername("MetaTable DB user-name");
dataSource.setPassword("MetaTable DB password");
return dataSource;
}
@Bean
@Primary
public DataSource tiberoBatchMetaTable() {
return tiberoBatchMetaTableProperties().initializeDataSourceBuilder().build();
}
// 비즈니스 DB 정보
@Bean
public DataSourceProperties batchDataSourceProperties() {
DataSourceProperties dataSource = new DataSourceProperties();
dataSource.setDriverClassName("비즈니스 DB driver-class-name");
dataSource.setUrl("비즈니스 DB url");
dataSource.setUsername("비즈니스 DB user-name");
dataSource.setPassword("비즈니스 DB password");
return dataSource;
}
@Bean
public DataSource tiberoDataSource() {
return batchDataSourceProperties().initializeDataSourceBuilder().build();
}
}
3.DB 설정 코드에서 Metatable 설정 부분을 추가 하였다.
import javax.sql.DataSource;
import org.springframework.batch.core.configuration.annotation.DefaultBatchConfigurer;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager;
@Configuration
public class TiberoBatchConfiguration extends DefaultBatchConfigurer{
@Autowired
@Qualifier("tiberoBatchMetaTable")
private DataSource tiberoBatchMetaTable;
@Autowired
@Qualifier("tiberoDataSource")
private DataSource tiberoDataSource;
@Autowired
private PlatformTransactionManager transactionManager;
@Autowired
private ApplicationContext applicationContext;
public TiberoBatchConfiguration() {
super();
}
public TiberoBatchConfiguration(DataSource dataSource) {
super(dataSource);
}
@Override
protected JobRepository createJobRepository() throws Exception{
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
factory.setDataSource(tiberoBatchMetaTable);
factory.setDatabaseType("ORACLE"); // Tibero Db 는 지원하지 않는 DB 기 때문에 지원되는 DB로 set
factory.setTablePrefix("원하는 스키마 설정");
factory.setTransactionManager(transactionManager);
factory.afterPropertiesSet();
return factory.getObject();
}
}
4.번 코드에서도 tiberoDB 로 JobRepository 를 설정하는 것이 아니라 Metatable 로 설정을 해주어야 한다.
factory.setDataSource(tiberoDataSource); -> factory.setDataSource(tiberoBatchMetaTable); 로 수정하였다.
'Java > Spring Batch' 카테고리의 다른 글
| Spring Batch + 구현 (0) | 2023.07.11 |
|---|---|
| Spring Batch + JPA ( feat. 티베로) (0) | 2023.06.27 |