강의

멘토링

커뮤니티

인프런 커뮤니티 질문&답변

기내식은수박바님의 프로필 이미지
기내식은수박바

작성한 질문수

죽음의 Spring Batch: 새벽 3시의 처절한 공포는 이제 끝이다.

1장. 작전3: Spring Batch Listener와 활용 (리스너... 실행과 죽음의 모든 순간을 지켜보는 자 ☠️)

리스너의 실무 로직

작성

·

33

1

킬구형 1장 - 작전3에서 아래와 같이 얘기한 부분에 대해 궁금한게 있어.

 

'리스너는 감시와 통제만 담당한다. 실제 시스템 제거 로직(비즈니스 로직)은 분리하라. 리스너가 너무 많은 일을 하면 유지보수가 어려워지고 시스템 동작을 파악하기 힘들어진다'

 

청크 기반 배치 잡이라고 하고 A라는 테이블에서 데이터를 읽어와서 B라는 테이블에 데이터를 삽입하는데 B 테이블에 데이터가 없다면 삽입, 있다면 수정하는 로직이 있어. 이 과정들이 모두 끝나고 마지막으로 B 테이블에 수정 날짜 컬럼이 잡 시작 시간보다 이르다면 A 테이블에 데이터가 없으므로 B 테이블에서 이러한 데이터들을 삭제하려는 로직을 넣는다고 했을 때 아래 궁금증들이 있어.

1. 위 얘기를 토대로 생각해보면 삭제 로직은 청크 기반 스텝 이후 태스크릿과 같은 다음 스텝으로 넣는게 좋은 것 같은데, 실무에서는 해당 잡 전용 리스너를 하나 추가로 만들어서 afterJob 메서드에 배치 상태가 COMPLETED인 경우에 삭제 로직을 실행하도록 하는 방식은 지양하는 편인거야? 전용 리스너를 만들어서 사용하는 경우도 있어?

  1. 만약 리스너에 삭제 로직을 넣는다고 했을 때 리스너에서 데이터 삭제 과정 중 오류가 발생한 경우에는 잡이 실패 상태로 종료되는거지?

  2. 2번과 같은 맥락인데 리스너에 삭제 로직을 넣는 경우 트랜잭션이 필요할텐데 리스너는 트랜잭션 범위가 어떻게 돼? 스텝에서는 청크 범위, 태스크릿의 반복 범위라고 본 걸로 기억하는데 리스너는 트랜잭션 설정 자체가 안되는건지 리스너 범위 내부에서만 설정되는건지 궁금해.

답변 2

2

KILL-9님의 프로필 이미지
KILL-9
지식공유자

기내식 형 형의 말이 맞다 💀

우리 강의에서도 챕터4 작전2 / 챕터5 작전4 등에서 리스너에 필요한 로직을 추가하는 내용을 담고있으면서 설명을 저렇게하고 있었다

저 부분은 표현을 좀 고칠 필요가있는데 다가올 스프링배치6 버전 작업에서는 저 표현은 제거되었다

해당 부분만 설명이 변경된게 아니라 아직 반영을못하였는데
주말간 현재 강의에도 수정분을 반영하겠다 💀💀

날카로운 지적이다

 

0

안녕하세요, 인프런 AI 인턴입니다.
기내식은수박바님께서 질문하신 내용은 Spring Batch에서 리스너와 비즈니스 로직의 적절한 배치와 처리에 관한 점입니다. 배치에서 리스너는 보조적 감시 역할을 수행하며, 복잡한 비즈니스 로직은 다른 컴포넌트로 분리해 유지보수를 용이하게 하는 것이 일반적인 권장 사항입니다.

1. 리스너와 비즈니스 로직

리스너를 통해 특정 로직을 실행할 수는 있지만, 리스너는 감시와 상태 보고에 집중하는 것이 목표입니다. 복잡한 비즈니스 로직은 스텝에서 개별적으로 처리하는 것이 좋습니다. 그러므로 청크 기반 스텝 이후, 삭제 로직을 별도의 태스크릿 스텝으로 분리하여 처리하는 것이 적절합니다. 그러나, 가벼운 로직에 대해서는 리스너를 사용하여 간단히 처리할 수도 있습니다. 실무에서는 전용 리스너를 만들어 사용하는 경우가 있지만, 이는 관리할 로직의 복잡성과 중요도에 따라 다릅니다.

2. 리스너 실행 중 오류 발생 시

리스너에서 오류가 발생하면 잡의 상태에 영향을 미칠 수 있습니다. 특히 afterJob 메서드에서 오류가 발생하면 잡이 이미 완료된 후에 실행되므로, 오류가 잡 자체의 상태를 실패로 변경하지는 않습니다. 하지만, 로그를 통해 예외의 발생을 기록할 수 있습니다. 적절한 예외 처리를 통해 리스너의 로직 실행 실패 시 원하는 동작을 구현할 필요가 있습니다.

3. 리스너의 트랜잭션 범위

리스너의 경우 보통 트랜잭션의 범위에 직접 포함되지 않습니다. 스프링 배치에서 청크 기반 처리나 태스크릿의 실행 단위는 명시적으로 트랜잭션 범위를 제공하지만, 리스너는 그러한 트랜잭션 범위에 포괄되지 않습니다. 필요에 따라 리스너 내부에서 수동으로 트랜잭션을 시작할 수 있지만, 리스너 설계에서는 이를 지양하는 것이 좋습니다. 대신, 필요한 경우 로직을 별도의 스텝으로 이동하고, 그 스텝에 트랜잭션을 적용하는 방식을 고려하시기 바랍니다.

관련하여 도움이 될 만한 자료입니다:

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

기내식은수박바님의 프로필 이미지
기내식은수박바

작성한 질문수

질문하기