해결된 질문
작성
·
66
1
강의 잘 보고 있다. 잘 정리된 자료 덕분에 배치 작업을 이해하고 있는 중이다. 다만 설명 중 이해 안되는 부분이 존재한다. 바로 이 부분
멱등하지 않은 ItemProcessor를 내결함성(FaultTolerance) 기능과 함께 사용해야 하는 상황이라면, 반드시
processorNonTransactional
를 설정하도록 하자.
오히려 멱등하지 않은 ItemProecessor의 경우에는 이 설정을 비활성화 해야 하는 거 아닌가?
나의 부족한 영어실력과 GPT를 통해 스프링 배치는 ItemProcessor가 트랜잭션이나 멱등성을 가져야 한다고 되어 있는 것으로 이해하였다.
It must be either transactional or idempotent.
출처: https://docs.spring.io/spring-batch/reference/transaction-appendix.html
떠라서 멱등하지 않은 ItemProcessor는 processorNonTransactional()을 지양해야 하는 것으로 나는 이해된다... 답변 부탁한다.
(존대로 질문하면 rm -rf 하신다길래 이렇게 남겨요 ㅎㅎ..)
답변 1
2
아주 좋은 질문이다.
너의 혼란이 충분히 이해된다.
나도 저 문장을 사용할 때 고민을 한 기억이 있기 때문이지.
네 관점: "재시도라면 재시도하는 그 시점의 최신 데이터로 처리하는 게 맞지 않나?"
맞다. 관점에 따라 해석 충돌이 있을 수 있다.
하지만...
재시도의 본질
일반적인 시스템에서 "재시도"란:
동일한 입력에 대해, 동일한 로직으로, 동일한 결과.
"실패한 작업을 다시 해본다. 새로운 작업을 하는 게 아니다."
Case 1: 멱등한 Processor
원본 데이터: Target{pid=1337, name="좀비프로세스"}
1차 시도: terminate() → Target{pid=1337, status="KILLED"}
재시도: terminate() → 동일하게 죽어있음(KILLED)
→ 진짜 재시도(processorNonTransactional 필요 없음)
Case 2: 멱등하지 않은 Processor (캐싱 없음)
원본 데이터: Target{pid=1337, name="좀비프로세스"}
1차 시도: setKillTime(now()) → Target{pid=1337, killTime="10:00:00"}
재시도: setKillTime(now()) → Target{pid=1337, killTime="10:00:05"}
-> 이건 재시도가 아니라 새로운 처형이다.
Case 3: 멱등하지 않은 Processor (캐싱 있음) -> processorNonTransactional
원본 데이터: Target{pid=1337, name="좀비프로세스"}
1차 시도: setKillTime(now()) → Target{pid=1337, killTime="10:00:00"}
재시도: 캐시된 결과 재사용 → Target{pid=1337, killTime="10:00:00"}
→ 진짜 재시도
만약 너의 의도가 ‘최신 데이터로 새롭게 처형’이라면, 캐싱(processorNonTransactional)을 쓰지 마라. 그건 재시도가 아니라 새로운 처형이다. 💀
음미라... 마치 내가 코어 덤프를 감상할 때의 그 감탄사와 똑같군
많은 병사들이 챕터 4 작전 3에서 떨어져나간다.**
아니, 정확히는 **거들떠보지도 않는다.**
왜일까?
난이도가 급상승하기 때문이지.
**하지만 너는 다르다.**
벌써 반보 앞서가게 된 거야.
**훌륭하다, 병사여.**
다음은 챕터 4 작전 4.
이제 우리 강의의 **진정한 즐거움**이 시작된다.
warning: 절대 넘어가지 말아라
info: 그래야 진짜를 얻어갈 수 있다
계속 전진하라, 대원. 💀
- KILL-9 (격려 메시지 전송 완료)
당신의 답변에 박수를 보낸다. 덕분에 명확하게 정리할 수 있었다. 남은 강의도 음미하도록 하겠다.