TASKLET 예제

2019. 1. 15. 23:52Spring Batch

반응형

TASKLET 구현 예제

대용량의 데이터 처리시 Reader->Processor->Writer 구현 방법 보다는 쿼리에서 INSERT SELECT 쿼리로 구현하는게 더 효과 적인 경우가 있다. 예를 들어 몇천만건 억단위건 데이터 처리시에는 INSERT SELECT로 구현하는 편이 낫다. 


이번 프로젝트 진행할때 최대 몇 십억 단위의 데이터를 INSERT SELECT 방식으로 집계 처리하는데에도 약 2~3시간이 걸렸었다.


Reader->Processor->Writer의 경우 데이터를 조회 하여서 조회 결과를 객체로 변환하여서 만약 로직이 있다면 로직처리 후 저장의 단계를 거치면서 시간이 많이 걸리게 될 것이다.


천만건 이상의 데이터 처리시에는 INSERT SELECT 쿼리로 구현이 가능하다면 이 방법을 사용 할 것을 권장 하며 그렇지 않고 Reader->Processor->Writer 구현은 Partitioning 처리가 효과 적이다.



그러면 TASKLET 구현에 대해 시작 해보자.

이번 예제는 BlackFridayFileToDbJob 예제 결과 테이블의 데이터를 집계 하여서 아래 생성한 테이블에 저장하는 과정에 대한 예제이다.



데이터베이스 테이블 생성


CREATE TABLE BLACK_FRIDAY_AGGRGT (
    USER_ID VARCHAR2(10 BYTE) NULL,
    PRODUCT_ID VARCHAR2(10 BYTE) NULL,
    GENDER VARCHAR2(5 BYTE) NULL,
    AGE VARCHAR2(10 BYTE) NULL,
    OCCUPATION VARCHAR2(2 BYTE) NULL,
    CITY_CATEGORY VARCHAR2(5 BYTE) NULL,
    STAY_IN_CURRENT_CITY_YEARS VARCHAR2(4 BYTE) NULL,
    MARITAL_STATUS VARCHAR2(5 BYTE) NULL,
    PRODUCT_CATEGORY_1 VARCHAR2(5 BYTE) NULL,
    PRODUCT_CATEGORY_2 VARCHAR2(5 BYTE) NULL,
    PRODUCT_CATEGORY_3 VARCHAR2(5 BYTE) NULL,
    PURCHASE VARCHAR2(10 BYTE) NULL
)

- 기존에 생성한 BLACK_FRIDAY와 같은 테이블 구조이다. 



BlackFridayAggrTasklet.xml 작성


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
						http://www.springframework.org/schema/beans/spring-beans.xsd
						http://www.springframework.org/schema/batch
						http://www.springframework.org/schema/batch/spring-batch.xsd">
						
	<job id="blackFridayAggrTaskletJob" xmlns="http://www.springframework.org/schema/batch">
		<step id="blackFridayAggrStep">
			<tasklet ref="blackFridayAggrTasklet" transaction-manager="transactionManager" />
		</step>
	</job>
	
	<!-- TASKLET BEAN 설정 -->
	<bean id="blackFridayAggrTasklet" class="com.batchguide.tasklet.CommonTasklet">
		<property name="sqlId" value="insertSelectBlackFridayForAggregation" />
	</bean>
	
</beans>

- CommonTasklet 클래스에서 Query Id를 파라미터로 받게 끔 처리하므로서 클래스 하나로 쿼리를 처리할 수 있

  다. 이번예제에는 파라미터 처리는 없지만 파라미터가 있는 경우 파라미터까지 넘겨 주도록 처리하면 될



CommonTasklet.java 작성


package com.batchguide.tasklet;

import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

public class CommonTasklet implements Tasklet {
	
	@Autowired
	@Qualifier("batchOracleSqlSessionTemplate")
	SqlSessionTemplate sqlSessionTemplate;
	
	private String sqlId;

	@Override
	public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
		sqlSessionTemplate.insert(sqlId);
		
		return null;
	}

	/**
	 * @return the sqlId
	 */
	public String getSqlId() {
		return sqlId;
	}

	/**
	 * @param sqlId the sqlId to set
	 */
	public void setSqlId(String sqlId) {
		this.sqlId = sqlId;
	}
}

- context-mapper.xml에 선언된 SqlSessionTemplate 총 4개이다 만약 위의 소스에서 @Qualifier를 지정하지 않

  는다면 에러가 날 것이다. 

  이번 예제는 오라클 DB를 사용하므로 @Qualifier 속성에 bbatchOracleSqlSessionTemplate 주었으며 배치모드

  로 처리한다.



SQL 작성


<insert id="insertSelectBlackFridayForAggregation"<
	INSERT /* insertSelectBlackFridayForAggregation| BlackFriday 집계데이터저장 | OracleQuerySQL.xml */ 
	  INTO BLACK_FRIDAY_AGGRGT 
		   (USER_ID
		  , PRODUCT_ID
		  , GENDER
		  , AGE
		  , OCCUPATION
		  , CITY_CATEGORY
		  , STAY_IN_CURRENT_CITY_YEARS
		  , MARITAL_STATUS
		  , PRODUCT_CATEGORY_1
		  , PRODUCT_CATEGORY_2
		  , PRODUCT_CATEGORY_3
		  , PURCHASE)
	SELECT USER_ID
		 , PRODUCT_ID
		 , GENDER
		 , AGE
		 , OCCUPATION
		 , CITY_CATEGORY
		 , MAX(STAY_IN_CURRENT_CITY_YEARS)		AS STAY_IN_CURRENT_CITY_YEARS
		 , MAX(MARITAL_STATUS)								AS MARITAL_STATUS
		 , MAX(PRODUCT_CATEGORY_1) 						AS PRODUCT_CATEGORY_1
		 , MAX(PRODUCT_CATEGORY_2) 						AS PRODUCT_CATEGORY_2
		 , MAX(PRODUCT_CATEGORY_3) 						AS PRODUCT_CATEGORY_3
		 , SUM(PURCHASE)											AS PURCHASE
	  FROM BLACK_FRIDAY 
	 GROUP BY USER_ID
			, PRODUCT_ID
			, GENDER
			, AGE
			, OCCUPATION
			, CITY_CATEGORY
			, MARITAL_STATUS
</insert<



[소스레파지토리]

☞ https://github.com/roopy1210/springbatch/blob/master/spring_batch_tutorial

반응형