Spring WebFlux에서 Kotlin Coroutine으로의 마이그레이션을 통해 코드 가독성과 유지보수성을 향상시킬 수 있다. Coroutine을 사용하면 예외 처리가 직관적이고 디버깅이 쉬워지며, 코드가 간결해진다. 마이그레이션 과정에서는 Controller, Service, Repository 레이어의 변화를 포함하여, 의존성 설정과 트랜잭션 처리 방법도 개선된다. 최종적으로 Coroutine을 사용하는 것이 코드의 가독성과 개발자 경험을 크게 향상시킨다.
JPA에서 지연 로딩과 JOIN FETCH의 차이를 설명하며, 과제 취소 기능 구현을 통해 성능 비교를 진행했다. 지연 로딩은 필요할 때 데이터를 로딩하는 반면, JOIN FETCH는 연관된 엔티티를 한 번의 쿼리로 조회하여 성능을 개선한다. 실제 성능 측정 결과, JOIN FETCH를 사용했을 때 약 32-43%의 성능 향상이 있었다. 조건부로 사용되는 연관 엔티티에는 지연 로딩을, 항상 함께 사용되는 경우에는 JOIN FETCH를 사용하는 것이 바람직하다.
Native Query를 Kotlin JDSL로 마이그레이션하면서 확장 함수 패턴을 도입했습니다. 일반 join을 fetchJoin으로 변경하여 N+1 쿼리 문제를 해결하고, 데이터베이스 레벨에서 직접 집계 연산을 수행하여 쿼리 성능을 개선했습니다. Kotlin JDSL의 타입 안전성과 확장 함수 패턴을 활용하여 유지보수성을 크게 향상시켰습니다.
JPA는 블로킹 I/O 모델을 사용하여 각 요청마다 별도의 스레드를 할당하고, 높은 동시성에서 많은 메모리와 스레드가 필요하다. 반면 R2DBC는 논블로킹 I/O 모델로 적은 수의 스레드로 많은 요청을 처리하며, 메모리 사용이 적고 높은 성능을 보인다. JPA는 복잡한 관계 매핑과 자동 쿼리 생성에 유리하고, R2DBC는 높은 동시성 요구사항과 리액티브 스택에 적합하다.
Spring Mail과 JavaMailSender를 활용하여 SMTP 프로토콜로 이메일을 전송하는 시스템을 구축했습니다. HTML 템플릿 기반 이메일, 파라미터 치환, Gmail SMTP 설정 등을 중심으로 실제 구현 과정을 공유합니다.
Spring의 @Transactional 어노테이션은 선언적 트랜잭션 관리 기능을 제공하며, Propagation 옵션을 통해 트랜잭션의 동작 방식을 설정할 수 있다. 주요 Propagation 옵션으로는 REQUIRED, REQUIRES_NEW, SUPPORTS, MANDATORY, NOT_SUPPORTED, NEVER, NESTED가 있으며, 각 옵션은 트랜잭션의 참여 및 생성 방식에 따라 다르게 작동한다. 실제 프로젝트에서의 활용 예시와 성능 최적화 팁도 포함되어 있으며, AOP 프록시 패턴을 기반으로 내부 구현 원리를 설명한다.