본문 바로가기
혼자 공부하는 것들/Spring

Spring Batch(+Mybatis)에서 Commit하기 전 실행된 SQL 문의 개수를 확인하고싶으면?

by applepick 2023. 7. 15.
반응형

정말 간단한 배치를 만들고 있었다. 복잡하지 않아서 Tasklet방식으로 만들었다. 간단히 설명하자면 하나의 Step에서 자료를 밀어 넣고 넣은 총개수를 다른 테이블에 넣어주는 작업이 있었다. 물론 step을 나눠서 하는 방법도 있었지만, 정말 간단한 배치고 일 년에 한 번 정도로 사용 빈도도 적어 하나의 Step에서 처리하고 싶었다. insert를 하고 commit 하기 전에 개수를 확인할 수 있는 방법은 없을까? 찾아보니 확인할 수 있는 방법이 있었다.

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.stereotype.Component;
import org.apache.ibatis.session.SqlSession;

@Component
public class taskletSample implements Tasklet {
    @Override
    public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
        // 대량 insert 작업 실행

        Long count = sqlSession.flushStatements().get(0).getUpdateCounts()[0]; //호출 할 시점에 commit 됨

        //카운트한 개수 타 테이블에 insert

        return RepeatStatus.FINISHED;
    }
}

간단한 샘플을 만들어봤다.

이런 식으로  commit 되기 전 시점에 insert한 개수를 알 수 있다.

 

 

궁금한 점!

1) 어떻게 가져오는거지?

- flushStatements() 이 메서드는 SqlSession 객체에 대기 중인 모든 SQL 문을 실행하고 실행된 SQL 문의 결과를 담은 List<int[]>를get(0)은 리스트에서 번째 요소인 int[] 배열을 가져온다. 다음으로 getUpdateCounts()[0]는 실행된 SQL 문의 업데이트 카운트를 포함한다. 0번째 값은 첫 번째 실행된 SQL 문의 업데이트 카운트를 가져온다. 결론적으로 첫 번째 실행된 SQL 문의 업데이트 카운트를 반환한다. insert, update, delete 등의 작업으로 인해 영향을 받은 행의 개수도 가져올 수 있다.

 

2) 위 방법이 좋은 방법일까?

 - 일반적으로는 개수를 가져오는 SQL문을 작성해서 처리하는 방법이 일반적이다. 다만, 배치에서 하나의 Step에 insert 작업과 count 작업을 분리할 수 없는 상황이라면 좋은 방법이다. 

 

3) commit 시점은 어떻게 되는 걸까?

 - sqlSession.flushStatements() 메서드를 호출하면 SqlSession 대기 중인 모든 SQL 문이 실행된다.  후에 commit() 메서드를 호출하여 데이터베이스에 트랜잭션을 커밋하게 된다. 따라서 sqlSession.flushStatements().get(0).getUpdateCounts()[0]를 호출할 , 해당 SQL 문이 실행되고 데이터베이스에 반영된 후에 업데이트 카운트를 가져오게 된다. 따라서 커밋이 이루어진 시점에서 insert 작업으로 인해 영향을 받은 행의 개수를 반환한다.

 

4) 만약 commit이 오류가 발생하면 반영되지 않은 count 값을 가져올 경우가 발생하지 않나?

- 맞다. 실패한 경우, sqlSession.flushStatements().get(0).getUpdateCounts()[0]에서는 이전 커밋 시점까지의 업데이트 카운트를 반환한다. 따라서, 실제로 반영되지 않은 업데이트 카운트를 가져오게 있다. 오류가 발생할 경우에는 예외 처리를 통해 문제를 처리하고, 필요에 따라 롤백 등의 추가적인 조치를 해줘야 한다. 업데이트 카운트를 정확하게 추적하고 사용하는 것이 중요하다.

 

 

혹시 더 좋은 방법이 있으면 댓글로 알려주세요!

 

회사에서 진짜 대용량 데이터를 배치 처리하면서 많이 성장하고 있다. 이번주 화요일은 kakao tech meet 오프라인에 참석한다. 

https://tech.kakao.com/2023/07/04/kakao-tech-meet-2/

 

제2회 kakao tech meet에 초대합니다!

kakao tech meet kakao tech meet은 카카오의 공개 기술 세미나로, 최신 기술 트렌드와 경험 및 노하우를 자주, 지속적으로 공유하며 개발자 여러분과 함께 성장을 도모하고 긴밀한 네트워크를 형성하고

tech.kakao.com

해당 세션 중 Spring Batch 애플리케이션 성능 향상을 위한 주요 팁 세션이 너무 궁금하다. 듣고 정리해 볼 예정이다. 끝!

반응형

댓글