Spring Batch : ChunkOrientedTaskletStep 순서도

    이 게시글은 인프런 정수원님의 강의를 복습하며 작성한 글입니다.

    ChunkOrientedTaskletStep 순서도

    앞선 게시글들에서 Chunk가 무엇인지, ChunkOrientedTaskletStep은 어떻게 이루어졌는지에 대해 공부를 했다. 조각조각된 내용들일텐데 이걸 하나로 모아서 한번 보려고 한다.

    1. Job에서 TaskLetStep으로 이동한다.
    2. TaskLetStep에서 RepeatTemplate을 이용해 반복을 실행한다.
    3. RepeatTemplate 내에서 ChunkOrientedTasklet을 반복적으로 수행해준다. 
    4. ChunkOrientedTasklet의 ChunkProvider에서 ItemReader로부터 값을 읽는다. 이 때, Repeat Template을 통해서 반복적으로 값을 읽는다. ItemReader가 시작할 때, 트랜잭션이 시작된다.
    5. ItemReader는 ChunkSize만큼 Repeat Template에서 값을 하나씩 반복해서 읽어오고 Input Chunk를 만들어 ChunkProcessor에 전달한다.
    6. ChunkProcessor는 itemProcessor에 Input Chunk를 하나씩 전달해서, output Chunk를 만들어온다. 
    7. Output Chunk를 ItemWriter에 전달하고, ItemWriter는 일괄적으로 DB에 쓰기 처리를 한다.
    8. Chunk 단위로 쓰기 처리가 완료되면, 4에서 시작된 트랜잭션은 종료된다.
    9. 또 리소스로부터 읽어야할 것이 있다면 4번부터 다시 시작한다. 

     

    이 때, ItemReader가 읽은 값이 Null이거나 Exception이 발생할 경우, 그 즉시 해당 Step이 종료된다. 트랜잭션은 롤백된다. 또 중요하게 봐야할 것은 Chunk Size 단위만큼 Transaction 내에서 처리가 되어 함께 움직인다는 것이다. 

     

     

    ChunkOrientedTaskletStep 코드로 확인하기

    Abstract Job - execute 메서드

    AbstractJob 클래스의 execute 메서드를 이용해 Job을 실행한다. 이 때, 내부적으로 doExecute() 라인에서 실제 Job이 수행된다. 

    SimpleJob.doExecute()

    SimpleJob 클래스의 doExecute() 메서드로 넘어온다. 여기서 handleStep(step, execution)을 통해 step이 실행된다.

    SimpleStepHandler.handleStep

    SimpleStepHandler.handlerStep 메서드로 넘어오면, 내부적으로 step.execute를 이용해 step을 실행해준다. 

    abstractStep.execute

    abstractStep.execute()로 넘어온다. 여기서 doExecute() 메서드를 통해 Step을 실행한다.

    taskletStep.execute()

    taskletStep.execute() 메서드로 넘어온다. 이 때, stepOperation.iterate 메서드에 RepeatTemplate을 만들어 넘겨준다. 

    taskletStep.execute()

    해당 Repeat Template에는 TransactionTemplate이 만들어진다. 이 TransactionTemplate을 만들고 execute 실행시켜준다. 여기서 Transaction 처리가 되고, Step이 실행된다. 

    transactiontemplate.execute()

    트랜잭션을 열어주고, doInTransaction에서 Step을 실행시켜준다.

    taskletStep.doInTransaction()

    taskletStep.doInTransaction()으로 넘어온다. 여기서 tasklet.execute()를 통해 tasklet이 실행된다.

    ChunkOrientedTasklet.execute()

    ChunkOrientedTaskLet.execute()로 넘어온다. 여기서 ChunkProvider.provide를 통해 리소스에서 Input Chunk를 불러온다.

    SimpleChunkProvider.provide

    SimpleChunkProvider는 repeatOpertaions.iterate()에 RepeatTemplate을 익명 클래스로 넘기면서 Item을 반복해서 읽는다.

    SimpleChunkProvider.provide()

    read()로 ItemReader로부터 Item을 읽어온다. 이 때, Exception이 발생하거나 item이 빈 값인 경우 RepeatStatus.Finished가 되면서 더 이상 반복되지 않는 것을 확인할 수 있다. 그리고 정상적으로 item을 읽어오면 inputs에 item을 추가하는 것을 볼 수 있다.

    ChunkOrientedTasklet.execute()

    Input Chunk를 받으면 이후 chunkProcessor.process를 통해 데이터 핸들링 및 쓰기 작업을 해준다. 

    SimpleChunkProcessor.process()

    transform을 통해 input Chunk를 output Chunk로 바꾸어준다. 

    simpleChunkProcessor.transform()

    전달받은 input Chunk를 For문을 이용해서 하나씩 item을 넘기면서 doProcess를 해준다. 

    simpleChunkProcessor.doProcess()

    doProcess 메서드에서는 itemProcessor.process(item)을 통해서 item을 단건으로 처리해주는 것을 볼 수 있다. 

    SimpleChunkProcessor.process

    이후 돌아와서 write 메서드를 통해 Write를 한다.

    simpleChunkProcessor.write

    write 메서드에서는 doWrite를 통해 OutPut Chunk를 넘겨준다.

    SimpleChunkProcessor.doWrite()

    doWriter 메서드에서는 writeItems를 통해서 items를 넘겨준다. 

    SimpleChunkProcessor.writeItmes

    wirteItems() 메서드에서는 itemWriter.writer 메서드에 items를 넘겨줘서 일괄로 쓰기를 처리하는 것을 확인할 수 있다. 

    ChunkOrientedTasklet.execute()

    write까지 완료되면 다시 chunkOrientedTasklet 객체로 돌아온다. 그리고 inputs에서 isEnd() 메서드를 이용해서 RepeatStatus 상태를 반환한다. 

    taskletStep.doInTransaction()

    다시 TaskletStep으로 돌아온다. 그리고 taskLetStep은 result에 저장된 RepeatStatus 상태를 반환해준다. 

    transactionTempleate.execute()

    반복 가능한지에 대한 결과값은 result에 담겨서 반환된다. 만약 여기서 Exception이 발생한 경우에는 RollBack을 하고 Exception을 터뜨리고, 그렇지 않은 경우에는 Commit을 한다. 그리고 다시 RepeatStatus 값을 반환해준다. 

     

    댓글

    Designed by JB FACTORY