Skip to content

refactor: AllAnalysisCompletedHandler 메서드 책임 분리 및 N+1 쿼리 개선#69

Merged
Boyeon-Shin merged 1 commit into
mainfrom
refactor/n-plus-one-query
May 5, 2026
Merged

refactor: AllAnalysisCompletedHandler 메서드 책임 분리 및 N+1 쿼리 개선#69
Boyeon-Shin merged 1 commit into
mainfrom
refactor/n-plus-one-query

Conversation

@Boyeon-Shin
Copy link
Copy Markdown
Collaborator

분리 및 N+1 쿼리 개선 (#68)

📌 관련 이슈 (Related Issue)

📝 작업 내용 (Description)

AllAnalysisCompletedHandler 메서드 책임 분리 및 N+1 쿼리 개선

🔄 변경 유형 (Type of Change)

  • ✨ 새로운 기능 (feat)
  • 🐛 버그 수정 (fix)
  • 📝 문서 수정 (docs)
  • 💄 스타일 (style)
  • ♻️ 리팩토링 (refactor)
  • ✅ 테스트 (test)
  • 🔧 기타 (chore)

✅ 체크리스트 (Checklist)

  • 코드가 정상적으로 동작하는지 확인했습니다
  • 기존 테스트가 통과합니다
  • 필요한 경우 새로운 테스트를 추가했습니다

@Boyeon-Shin Boyeon-Shin self-assigned this May 5, 2026
@Boyeon-Shin Boyeon-Shin changed the title refactor: AllAnalysisCompletedHandler 메서드 책임 refactor: AllAnalysisCompletedHandler 메서드 책임 분리 및 N+1 쿼리 개선 May 5, 2026
@Boyeon-Shin Boyeon-Shin merged commit 34e18f5 into main May 5, 2026
3 checks passed
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the AllAnalysisCompletedHandler to improve modularity and performance, notably by optimizing database interactions through batch fetching of answers and feedbacks. The review feedback points out a critical issue where the @transactional annotation on the handle method might prevent session failure states from being saved due to transaction rollbacks. Additionally, it suggests using a merge function in Collectors.toMap to prevent potential exceptions and recommends reusing already loaded objects to avoid redundant database lookups during error handling.

@@ -48,92 +50,133 @@ public class AllAnalysisCompletedHandler {
@Transactional
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

handle 메서드에 @Transactional이 선언되어 있어, 내부 로직 수행 중 런타임 예외가 발생하면 해당 트랜잭션은 rollback-only로 마킹됩니다. 이 경우 catch 블록에서 호출하는 failSession 메서드 내의 DB 저장 로직(sessionRepository.save)이 정상적으로 반영되지 않아, 세션 상태가 FAILED로 변경되지 않는 문제가 발생할 수 있습니다. 비즈니스 로직의 실패 여부와 관계없이 세션 상태를 업데이트하려면 트랜잭션 경계를 적절히 분리하거나 failSession을 별도의 트랜잭션(예: Propagation.REQUIRES_NEW)으로 처리하는 것을 권장합니다.

List<InterviewQuestion> questions = questionRepository.findByInterviewSessionId(sessionId);

Map<UUID, InterviewAnswer> answerMap = answerRepository.findBySessionId(sessionId).stream()
.collect(Collectors.toMap(a -> a.getInterviewQuestion().getId(), a -> a));
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Collectors.toMap 사용 시 중복된 키(동일한 questionId를 가진 답변)가 존재할 경우 IllegalStateException이 발생할 수 있습니다. 현재 비즈니스 로직상 질문당 하나의 답변만 존재한다고 가정하더라도, 예기치 못한 데이터 중복 상황에 대비하여 merge function을 추가하는 것이 안전합니다.

Suggested change
.collect(Collectors.toMap(a -> a.getInterviewQuestion().getId(), a -> a));
.collect(Collectors.toMap(a -> a.getInterviewQuestion().getId(), a -> a, (existing, replacement) -> existing));

}

private void failSession(UUID answerId, String message) {
InterviewAnswer answer = answerRepository.findByIdWithQuestionAndSession(answerId).orElse(null);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

failSession 메서드에서 answerRepository.findByIdWithQuestionAndSession(answerId)를 호출하여 세션 정보를 조회하고 있습니다. handle 메서드에서 이미 answer 객체를 조회한 상태라면 이를 재사용하여 불필요한 DB 조회를 줄일 수 있습니다. 또한, answerId가 유효하지 않을 경우 세션 실패 처리가 누락될 수 있으므로, 이벤트 객체에 sessionId를 포함하거나 조회 방식을 개선하는 것을 고려해 보세요.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

refactor: AnalysisCompletedHandler N+1 쿼리 개선

1 participant