TL;DR상품 목록 조회 시 좋아요 수 정렬을 위해 Like 테이블과 JOIN하니 인덱스가 적용되지 않아 성능이 나빴다. Product 테이블에 likeCount 컬럼을 비정규화하고 인덱스를 추가해 성능을 개선했다. 읽기가 쓰기보다 압도적으로 많은 상황에서는 정합성 동기화 비용보다 조회 성능 개선이 더 중요하다고 판단했다.문제 상황커머스 서비스에서 상품 목록 API에 다음 기능을 추가하려고 했다.요구사항브랜드별 필터링좋아요 수 기준 정렬로컬에서 소량 데이터로 테스트할 땐 괜찮았는데, 10만 건 데이터를 넣고 테스트하니 성능이 나빴다.AS-IS: 초기 구현 (인덱스 없음)좋아요 수로 정렬하기 위해 Like 테이블과 LEFT JOIN 후 COUNT를 했다.SELECT p.id, p.name, ..
분류 전체보기
TL;DR재고, 포인트, 쿠폰처럼 충돌 빈도가 높고, 실패 시 이미 수행한 작업을 롤백하고 처음부터 다시 시도해야 하는 경우 비관적 락이 더 적합하다고 판단했다. 낙관적 락은 충돌이 드물고, 실패해도 해당 작업만 다시 시도하면 되는 상황에 더 맞지 않을까 생각한다. 문제 상황커머스 서비스에서 주문 기능을 구현하면서, 동시성 이슈를 마주했다.@Transactionalfun createOrder(userId: Long, items: List, couponId: Long? = null): Order { val orderProducts = deductStock(items) // 1. 재고 차감 val totalAmount = calculateTotalAmount(orderProducts) ..
모든 걸 mock 하면 진짜 로직은 누가 검증하는가?TL;DR단위 테스트에서 모든 의존성을 mock 처리하면 테스트는 통과하지만, 정작 중요한 도메인 로직은 검증되지 않는다. StockService를 mock에서 실제 구현체로 전환하며 느낀 "단위 테스트의 진짜 목적"에 대한 이야기. 문제를 발견한 순간주문 기능의 단위 테스트를 작성하던 중, 이런 코드를 작성했다.class OrderFacadeTest { private val stockService: StockService = mockk() @Test fun throwsException_whenStockIsInsufficient() { val currentStock = 50 val requestQuantity =..
TL;DR요구사항 명세서는 백엔드 개발자끼리 보는 기술 문서가 아니다.비개발 직군과의 소통 도구이며, "이거 제가 원한 게 아닌데요?"라는 말을 듣지 않기 위해, 그리고 놓친 케이스를 함께 찾아내기 위해 작성하는 문서다. 그래서 BAD_REQUEST 대신 "재고가 부족합니다"라고 써야 한다.시작하며이번 주 e-commerce 프로젝트를 시작하면서 가장 먼저 작성한 건 요구사항 명세서였다.사실 처음엔 이런 생각이 들었다.“이거 꼭 써야 하나? 어차피 코드로 구현하면 되는데... 문서 작성에 시간을 쓰는 게 비효율적인 거 아닌가?”하지만 막상 써보니 생각이 완전히 달라졌다.작성하는 과정 자체가 팀 전체의 이해를 맞추는 과정이었다.이 문서는 누구를 위한 것인가?처음엔 요구사항 명세서를 개발자를 위한 설계 문서..
TL;DRRepository 메서드명을 getXXX()대신 findByXXXOrNull()로 작성한 이유는, 메서드명만 보고도 null 가능성을 인지하고 안전하게 처리하도록 유도하기 위함이었다.# Repository 네이밍 컨벤션## 조회 메서드- findByXxxOrNull(): null을 반환할 수 있는 조회- getByXxx(): 없으면 예외를 던지는 조회## 예시- findByUsernameOrNull("user123") → User? 반환- getByUsername("user123") → User 반환 또는 예외자연스럽게 작성했던 getUser()interface UserRepository { fun getUser(username: String): User?}"유저를 가져온다(get)" -..
개요이 글에서는 runBlocking, launch, async 등 주요 코루틴 빌더를 직접 실습하며, 그 동작 원리와 예외 처리, 취소 등 실무에서 반드시 숙지해야 할 코루틴 사용법을 하나씩 짚어본다. 목표코루틴의 정의와 개념 이해runBlocking, launch, async 등 다양한 코루틴 빌더의 사용법 습득코루틴의 취소, 예외 처리, 병렬 처리 등 실무 활용 방법 이해 코루틴이란'Coroutine'은 'co-operative routine', 즉 협력하는 루틴이라는 의미이다. 코틀린(Kotlin)의 'Ko'가 아니라, 여러 루틴이 협력하여 실행 흐름을 제어한다는 의미의 'co'가 붙은 것이다. 코루틴은 멀티스레드 환경에서 발생할 수 있는 복잡성과 자원 소모를 줄이며, 경량화된 비동기 처리를 가능..