장애와 삽질이 가르쳐 준 것들
실무에서 만난 문제들을 기록합니다.
Spring 장애
JPA N+1, 배치 지연, 스케줄러 데드락 — 실전 트러블슈팅 모음
아키텍처
SAGA, 분산락, 데이터 정합성 — 설계 원칙부터 분산 시스템까지
AI/DX
Claude Code, MCP, AI 에이전트 — 백엔드 개발자의 AI 전환 가이드

JWT는 은총알이 아니다 - Access/Refresh Token 설계와 대용량 Redis 인증
TL;DR 배경: “JWT 쓰면 세션보다 좋다면서요?”로 시작된 인증 설계 회의에서 반복된 실수와 운영 이슈 정리 함정 4종: Stateless 환상, localStorage 저장, RT 단일 발급, 로그아웃 미구현 탈취 대응: Reuse Detection, 디바이스 핑거프린트, 지리적 이상 감지 → 강제 세션 종료 대용량 운영: Redis 블랙리스트 + Bloom Filter, RT는 DB에 풀 저장 / Redis는 핫…

캐시 테이블 불일치로 인한 전자계약 발송 실패 - Spring Cache의 숨겨진 함정
TL;DR 증상: 전자계약 발송 시 간헐적 NPE, DB에는 데이터 존재 원인: 동일 도메인 데이터를 4개 캐시 이름으로 분산 + Repository/Entity 테이블 불일치 해결: 단일 캐시로 통합, 올바른 서비스 주입, 레거시 @Deprecated 후 삭제 계획 효과: NPE 재현 불가, 캐시 히트율 정상화, 모니터링 지표 확보 한계: 로컬 캐시는 중앙 관리 불가 → 네이밍 사고에 여전히 취약

스케줄러 배치가 어쩔 땐 성공하고 어쩔 땐 실패한 이유 - 데드락 해결기
TL;DR 증상: 10분마다 실행되는 스케줄러가 간헐적으로 데드락 발생 (시간당 3회) 원인: 약 20초간 긴 트랜잭션으로 전체 테이블 Lock 유지, API 서버와 Lock 경합 해결: 4가지 방법 적용 (필터링, 트랜잭션 분리, REQUIRES_NEW, 500개 Chunking) 효과: 데드락 발생 주 3~4회 → 0회, Lock 유지 시간 99.9% 감소 (20초 → 1ms) 한계: Chunking으로 처리 시간 증가…

200줄 메서드를 파사드 패턴으로 정복하기
TL;DR 문제: 200줄짜리 메서드, 스크롤 끝이 안 보임, 수정할 때마다 겁남, 6개월 후 이해하는 데 30분 소요 원인: 외부 API 호출 + 검증 + 변환 + 저장 + 예외 처리가 한 메서드에 몰려 있음 해결: 파사드 패턴 - 큰 메서드를 작은 서비스로 쪼개고, Facade가 조합 담당 효과: 200줄 → 30줄, 읽는 시간 30분 → 5분, 테스트 쉬움 (각 서비스 독립) 한계: 초기 분리 시간 (1주…

시니어도 헷갈리는 @Transactional 실수 5가지
TL;DR 문제: Checked Exception 발생 시 데이터가 롤백되지 않고 일부만 저장됨 (데이터 정합성 깨짐) 원인: Spring @Transactional이 기본적으로 RuntimeException과 Error만 롤백하고, Private 메서드나 예외 삼키기 등 다양한 함정 존재 해결: RuntimeException 사용, Public 메서드에만 적용, 예외 삼키기 금지, 전파 속성 이해 효과: 트랜잭션…

실무에서 바로 쓰는 JPA (5편) - 실무 안티패턴 총정리
TL;DR 문제: N+1, 영속성 컨텍스트, 쿼리 최적화, 엔티티 설계 등 JPA 실무 안티패턴이 복합적으로 발생 원인: 각 주제를 개별적으로 다뤘지만, 실무에서는 여러 문제가 동시에 나타남 해결: JPA 시리즈 1~4편 내용을 한 곳에 모아 체크리스트로 정리 효과: 코드 리뷰 시 빠른 확인, 리팩토링 가이드, 신규 팀원 온보딩 자료 한계: 시리즈 전체를 읽어야 완전히 이해, 체크리스트만으로는 깊이 부족, 실전 경험…

실무에서 바로 쓰는 JPA (4편) - 엔티티 설계 마스터하기
TL;DR 문제: 양방향 연관관계 남발, cascade 무분별 사용, setter 도배로 엔티티 설계가 엉망 원인: N+1, 영속성 컨텍스트, 쿼리 최적화는 했는데 근본 원인은 엔티티 설계 해결: 단방향 우선, cascade 최소화, setter 제거 (Builder 패턴), 불변 객체 효과: 순환참조 방지, 의도치 않은 수정 방지, 테스트 쉬움, 유지보수성 ↑ 한계: 초기 설계 시간 증가, 연관관계 추가 시…

실무에서 바로 쓰는 JPA (3편) - 쿼리 최적화 실전
TL;DR 문제: 복잡한 조건의 동적 쿼리, 컬렉션 2개 이상 Fetch Join, 페이징 + 조인 등 실무 쿼리가 어려움 원인: N+1, 영속성 컨텍스트 해결했지만 복잡한 쿼리는 별도 최적화 필요 해결: QueryDSL + Projection (DTO 직접 조회), Batch Size 조합, 필요한 컬럼만 조회 효과: 응답 시간 3초 → 300ms, 데이터 전송량 50% 감소, 동적 쿼리 깔끔 한계: QueryDSL…

실무에서 바로 쓰는 JPA (2편) - 영속성 컨텍스트와 흔한 실수들
TL;DR 문제: N+1 문제 해결했지만, 영속성 컨텍스트 미이해로 예상치 못한 쿼리 발생, 테스트 느림 원인: 영속성 컨텍스트가 엔티티를 자동으로 캐싱하는데, 이 메커니즘을 모르고 사용 해결: 1차 캐시 이해, 변경 감지, 준영속 상태, 트랜잭션 범위 명확화 효과: 불필요한 쿼리 감소, 영속성 컨텍스트 활용한 최적화, 테스트 안정화 한계: 개념 이해 필수 (러닝 커브), 1차 캐시는 트랜잭션 내에서만, 대용량 처리…