seeun's tech blog

비즈니스 병목을 기술적 표준과 아키텍처로 해결하는 Backend Engineer

데이터 파이프라인, 분산 시스템, 소프트웨어 아키텍처에 대한 경험과 인사이트를 공유합니다.

주요 기술 스택

Spring BootSpring Boot
NestJSNestJS
KafkaKafka
KubernetesKubernetes
MongoDBMongoDB
Node.jsNode.js
PostgreSQLPostgreSQL

Spring의 @Transactional 어노테이션은 선언적 트랜잭션 관리 기능을 제공하며, Propagation 옵션을 통해 트랜잭션의 동작 방식을 설정할 수 있다. 주요 Propagation 옵션으로는 REQUIRED, REQUIRES_NEW, SUPPORTS, MANDATORY, NOT_SUPPORTED, NEVER, NESTED가 있으며, 각 옵션은 트랜잭션의 참여 및 생성 방식에 따라 다르게 작동한다. 실제 프로젝트에서의 활용 예시와 성능 최적화 팁도 포함되어 있으며, AOP 프록시 패턴을 기반으로 내부 구현 원리를 설명한다.

AOP
JPA
Spring
읽기

JPA에서 지연 로딩과 JOIN FETCH의 차이를 설명하며, 과제 취소 기능 구현을 통해 성능 비교를 진행했다. 지연 로딩은 필요할 때 데이터를 로딩하는 반면, JOIN FETCH는 연관된 엔티티를 한 번의 쿼리로 조회하여 성능을 개선한다. 실제 성능 측정 결과, JOIN FETCH를 사용했을 때 약 32-43%의 성능 향상이 있었다. 조건부로 사용되는 연관 엔티티에는 지연 로딩을, 항상 함께 사용되는 경우에는 JOIN FETCH를 사용하는 것이 바람직하다.

JPA
LazyLoading
Join
읽기
2025.09.28
3

DTO는 계층 간 데이터 전송을 위한 가변 객체로, API 요청/응답에 주로 사용되며 검증 로직이 최소화된다. 반면, VO는 값 자체를 표현하는 불변 객체로, 데이터의 목적과 특성이 다르다.

DDD
Decorator
VO
읽기

낙관적 락은 충돌이 적을 때 사용되며, 저장 시 버전을 확인하여 충돌을 감지한다. Spring Data R2DBC를 통해 자동으로 버전 관리가 이루어지고, 동시성 충돌 발생 시 재시도 메커니즘이 작동한다. 장점으로는 읽기 성능과 동시성 처리, 데드락 방지가 있으며, 단점으로는 충돌 시 재시도 필요성과 복잡성이 있다.

optimistic lock
읽기

Spring WebFlux에서 Kotlin Coroutine으로의 마이그레이션을 통해 코드 가독성과 유지보수성을 향상시킬 수 있다. Coroutine을 사용하면 예외 처리가 직관적이고 디버깅이 쉬워지며, 코드가 간결해진다. 마이그레이션 과정에서는 Controller, Service, Repository 레이어의 변화를 포함하여, 의존성 설정과 트랜잭션 처리 방법도 개선된다. 최종적으로 Coroutine을 사용하는 것이 코드의 가독성과 개발자 경험을 크게 향상시킨다.

coroutine
kotlin
읽기

JPA는 블로킹 I/O 모델을 사용하여 각 요청마다 별도의 스레드를 할당하고, 높은 동시성에서 많은 메모리와 스레드가 필요하다. 반면 R2DBC는 논블로킹 I/O 모델로 적은 수의 스레드로 많은 요청을 처리하며, 메모리 사용이 적고 높은 성능을 보인다. JPA는 복잡한 관계 매핑과 자동 쿼리 생성에 유리하고, R2DBC는 높은 동시성 요구사항과 리액티브 스택에 적합하다.

kotlin
r2dbc
rdbms
읽기

Google Gemini CLI 오픈소스 프로젝트에 기여하여 토큰 에러 핸들링 시스템을 구현하였습니다. 이 시스템은 자동 복구 및 재시도 메커니즘을 통해 긴 입력에 대한 처리 문제를 해결하며, 사용자 친화적인 에러 메시지와 실시간 토큰 모니터링 기능을 제공합니다. 또한, 다양한 에러 형태를 지원하고, 성능 최적화를 위해 비동기 처리 및 지수 백오프를 적용하였습니다. 향후 스마트 컨텍스트 압축 및 실시간 대시보드와 같은 추가 기능을 고려하고 있습니다.

gemini
google
test
읽기

MongoDB의 멀티 도큐먼트 트랜잭션을 Node.js에서 안전하게 구현하기 위해 AsyncLocalStorage와 Mongoose 미들웨어를 사용하는 방법을 설명하며, 자동 세션 관리, 재시도 메커니즘, 에러 처리 및 성능 최적화의 중요성을 강조합니다. 다양한 구현 방식을 비교하고, @Transactional 데코레이터를 통해 복잡한 비즈니스 로직을 안전하게 처리하는 방법을 제시합니다.

MongoDB
transaction
AsyncLocalStorage
Nodejs
Mongoose
Nestjs
읽기

Kafka 메시지 처리를 위해 각 토픽마다 개별 컨슈머 그룹을 구성하고, 커스텀 데코레이터(@Consume)를 통해 컨트롤러의 특정 메서드를 Kafka Consumer로 등록하는 방법을 설명합니다. NestJS에서 데코레이터는 마킹, 조회, 등록의 3단계로 동작하며, 이를 통해 독립적인 오프셋 관리, 맞춤형 소비 로직, 리밸런싱 영향 최소화 등의 장점을 제공합니다.

Nestjs
AOP
Decorator
kafka
읽기