본문으로 바로가기

[SPRING] Spring Batch vs DB Procedure

category JAVA/기본 상식 2021. 7. 22. 23:57

현 회사에서 내가 맡은 부서는 아직 DB 프로시저로 배치가 이루어지고 있다.

 

다른 서비스영역은 이미 스프링 배치가 돌아가고 있었고 언젠가는 작업을 해야 될 것이다.

 

문뜩 그런 생각이 들었다. 트렌드도 트렌드지만 왜 바꿔야할까? 그리고 장단점이 분명히 있을텐데 생각이 들면서

 

작업전에 사전조사를 했다.

 

DB 프로시저는 다뤄볼일이 거의 없고 현재는 운영에 가깝다보니 보정작업을 위주로 하고 있음으로써

 

나 역시 DBA 전문가가 아니다보니 유지보수를 하면서 찾는데 시간이 더욱 더 걸리는 부분은 부정할 수 없다.

 

기본적으로 프로시저가 돌게 되면 네트워크 통신도 없고, 메모리는 DB Server에서만 사용되다보니

 

리스크가 적다는 장점을 가지고 있다.

 

스프링배치를 적용하게 되면 가장 큰 장점은 아래와 같습니다.

 

1. 버전관리, 배포를 웹어플리케이션과 같은 방식으로 할 수 있습니다. (프로시저보다 관리가 편리함)

2. 부분적으로 테스트하기에 편리함. (유닛 테스트)

3. 꼭 DB서버가 하지 않아도 되는 작업은 다른 서버로 분리해서 DB서버의 자원을 조금이나마 절약하는 의미도 있습니다.  DB서버는 분할해서 구성하는 비용이 크므로 대용량시대에는 가장 아껴야할 자원인데, 어플리케이션서버는 상대적으로 여러대로 늘이는 구성이 어렵지 않습니다. 스프링배치에서도 여러서버를 써서 분산처리하는 구성도 가능합니다.

4. 스프링배치를 쓴다면 배치 모듈을 세분화해서 추후에 기능을 추가하거나 에러를 재현하기 쉬운 구조로 유도합니다.

 

프로시저의 장점

1. xml파일을 한 꺼번에 메모리에 안 올리고 부분처리

2. Job전체을 한번의 transaction으로 가지고 가지 않고 commit 주기별로 끊어서 처리

3. 코드에 침범적이지 않은 시작,실패 이벤트처리

 

그렇다면 프로시저가 속도가 더 빠른거 아닌가요?

- Java로 만든 배치가 DB 프로시저의 성능은 뛰어 넘을 수 없습니다.

  Java로 만든 배치로 만든 배치는 WAS에서 호출되다 보니 네트워크 호출비용, JDBC 드라이버의 콜스택을 거치게 됩니다.

※ 날이 갈수록 DB프로시저를 권장하지 않는 이유

DB프로시져로도 잘 짠다면 유지보수성에 문제가 없을수도 있지만, 닷넷기반과 콜라보로 Mybatis, JPA에 익숙한 자바 개발자들이 확인 하기에는 DB담당자외에는 손댈수가 없는 현상을 맛보게 됩니다.

 

그렇다면 DB 프로시저에서 스프링 배치로 전환하는 예시를 한번 실습해보자.

 

프로시저

CREATE PROCEDURE storedProcName @numbers VARCHAR(max), @day DATE
AS
SET NOCOUNT ON;

SELECT something, something2, something3
FROM sometable
WHERE ids in (select value from string_split(@numbers,','))
AND day = @day

 

스프링 배치 (사용자 지정 행 매퍼)

public class CustomRowMapper implements RowMapper<CustomObject> {
    private static final String SOMETHING = "something";
    private static final String SOMETHING2 = "something2";
    private static final String SOMETHING3 = "something3";

    @Override
    public CustomObject mapRow(ResultSet resultSet, int i) throws SQLException {
        CustomObject customObject = new CustomObject();
        customObject.setSomething(resultSet.getString(SOMETHING));
        customObject.setSomething2(resultSet.getString(SOMETHING2));
        customObject.setSomething3(resultSet.getInt(SOMETHING3));

        return customObject;
    }
}

 

저장 프로 시저를 실행하고 결과를 쿼리합니다.

 

SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate)
        .withProcedureName("storedProcName")
        .returningResultSet("test", new CustomRowMapper());
Map<String, Object> out = jdbcCall.execute(parameterSource);
List<CustomObject> customObjects = (List<CustomObject>) out.get("test");

 

현재는 이 정도로만 정리하고, 스프링배치 교육을 통한 실습을 하면서 회사에도 이바지할수 있는게 올해의 목표이다.

 

참고 사이트 : https://www.kejisen.com/ko/article/197782105.html