작성
·
433
·
수정됨
0
ItemWriter에서 '12' 아이템이 예외가 터져서 Skip처리 되고, 다시 ItemReader 부터 재실행 되는 것은 이해했습니다.
근데 ItemProcessor에서 '6'과 '7' 을 Skip처리한 거처럼
ItemWriter역시 마찬가지로 ExecutionContext에 '12' 아이템이 저장되므로 ItemProcessor와 ItemWriter에서 '12' 아이템은 Skip 해야 되지 않나요?
그러면 출력값에 6, -6과 7, -7이 안뜬거 처럼
12, -12는 안떠야 된다고 생각합니다.
답변 1
1
네
프로세스는 말씀하신 것처럼 흐르고 있습니다.
다만 ItemWriter 에서 예외가 발생해서 처리되는 skip 동작은 ItemReader 나 ItemProcessor 와는 약간 다르게 동작합니다.
코드를 보시면 ItemWriter 에서 -12 값을 처리할 때 예외가 발생해서 처리하지 못합니다
이 때 ItemWriter 에서 ItemWriter : -12 가 출력되었습니다.
그러면 skip 기능이 동작해서 ItemProcessor 로 가는데 ItemProcessor 는 자신이 가지고 있는 outputs 에서 다시 시작합니다. 즉 {12,13,14,15,16} 에서 시작합니다.
이 때 ItemProcessor : 12 가 출력되었습니다.
그리고 ItemWriter 에게 {-12,-13,-14,-15,-16} 를 다시 던저 주게 됩니다.
그러면 ItemWriter 에서 -12 를 처리해야 하기 때문에 다시 예외를 발생하게 됩니다.
이 때 ItemWriter 에서 ItemWriter : -12 가 출력되었습니다.
이후부터는 ItemProcessor 에서 12 를 스킵하고 {13,14,15,16} 을 가지고 다시 시작하게 됩니다
그러면 12 는 제외가 되기 때문에 ItemWriter 에서 예외가 발생하지 않고 정상적으로 실행이 됩니다.
이 흐름을 본다면 ItemWriter 에서 예외가 발생해서 스킵 기능이 동작하게 된다면 실제 데이터를 다시 리셋해서 전달하는 쪽은 ItemProcessor 이기 때문에 ItemWriter 에서는 단지 ItemProcessor 에서 전달하는 데이터를 다시 받게 되는 상황이 발생해서 마치 두번 실행되는 것처럼 여겨 질수 있는데 이는 스프링 배치에서 정해놓은 규칙에 불과합니다.
예외는 ItemWriter 에서 발생해서 skip 기능이 동작했지만 실제 데이터를 skip 하는 것은 ItemProcessor 에서 하게 되고 ItemWriter 는 전달받은 데이터를 처리하는 역할만 하게 됩니다.
핵심은 ItemWriter 에서 최종적으로 -12 가 저장되지 않는 것이 중요하고 실제로 그렇게 처리가 되고 있습니다
콘솔에 출력되는 것은 흐름에 따른 과정일 뿐 결과론적으로는 스킵기능이 정상적으로 동작하고 있습니다
디버깅 하면서 찬찬히 따라가 보시면 더 이해가 되실 거라 봅니다.
아, 다른 블로그를 찾아보다가 이해하게 됐어요.
최초에는 ItemProcessor 가 [12, 13, 14, 15, 16] 을 리스트로 한번에 넘김
12 를 처리하다 Exception 발생
두번째, ItemProcessor 가 12, 13, 14, 15, 16 을 각각 1개씩 넘김.
12가 에러가 발생하여 Skip 하고 13부터 다시 진행.
헷갈렸던 이유 :
정상 동작 시 ItemProcessor 가 ItemWriter 에 List 로 한번에 넘긴다는 사실을 깜빡함
예제에서 for문 내부에 각 item 마다 로그를 찍어서 1번 사실을 망각하고 넘어감.
저도 이부분이 이해가 잘 안돼서 Q&A 봤는데 똑같이 이해가 안되시는 분이 계시네요..
사실 답변을 봐도 잘 이해가 가지 않습니다.
답변을 보고 궁금한점은요,
ItemWriter 에서는 -12를 처리하다가 Exception 이 발생해서 Skip을 했는데 왜 Processor 는 12를 또 처리하는건가요? 그렇게 치면 2번째 skip 할 때도 Processor 는 12를 계속 처리해야 할텐데, 왜 2번째 skip 에서는 12를 제외하고 재시도를 하게되는건지요. 단지 스프링이 정해놓은 규칙이라고만 이해하기에는 이해가 잘 되지 않습니다.
그러면, 위 설명대로라면 ItemWriter 에서 Skip Limit 은
ItemWriter 에서 발생할 skip 횟수 * 2
로 설정해야만 정상적으로 돌아가야 하는건가요?이게 스프링의 버그가 아니라면, 어떤 의도로 이렇게 개발된 것일지 궁금합니다.