전체 글 73

락은 왜 느리고, MVCC는 무엇을 바꾸었나

1) 락은 왜 느려질까 → 그래서 MVCC가 나왔다락의 본질: “같은 리소스를 만지는 트랜잭션을 순서로 묶는다.”순서를 강제하면 안전은 올라가지만 대기(Blocking) 가 생긴다.읽기까지 줄 세우면: 쓰기 충돌이 많을수록 읽기도 연쇄적으로 대기 → TPS 하락, 지연 증가, 데드락 위험 상승.해결 철학: “읽기는 줄 세우지 말자.” → MVCC (Multi-Version Concurrency Control)같은 행의 여러 버전을 보관하고, 각 트랜잭션은 자기 시점의 스냅샷만 읽는다.→ 읽기는 락 없이 병렬, 쓰기끼리만 충돌 처리.2) MVCC, 도대체 뭔데 이렇게 빠르지?Undo Log + TRX_ID: InnoDB는 변경 전 값을 Undo Log에 보관하고, 각 레코드에 내부 트랜잭션 ID를 붙인다...

Loopers 2025.08.10

동시성 제어, 도메인 분리를 삼킨 괴물

도메인이 협력할 때 진짜 문제는 시작된다이번 Loopers 과제의 요구사항은 동시성 관리였다.사용자는 상품을 주문할 수 있어야 한다.주문 시 사용자의 포인트가 차감되고, 쿠폰을 사용하면 할인이 적용되며, 상품 재고도 줄어야 한다.단순한 흐름 같지만, 이걸 도메인 책임을 분리하면서 트랜잭션 정합성까지 보장하려면 이야기가 달라진다.1. 할인 정책은 주문(Order)의 책임이 아니다왜 이게 문제였는가?처음엔 Order 도메인에서 할인 금액 계산까지 전부 처리하고 있었다.public static Order create(UserId userId, List items, UserCoupon coupon) { validate(userId, items); OrderAmount originalAmount = O..

Loopers 2025.08.08

설계는 정답이 없다고 했지만, 그래도 너무 어렵잖아

🧭 시작은 단순했습니다Loopers 과제 Round 3에서는상품, 브랜드, 좋아요, 주문, 결제 도메인을 구현해야 했습니다.기능만 보면 단순한 CRUD처럼 보였지만,실제로는 도메인 간 협력, 구조 확장, 책임 분리 등설계 측면에서 많은 고민이 필요했습니다.📦 1. 상품 조회 – 정렬 기준이 늘어날수록 구조는 어떻게 바뀔까?처음엔 이렇게 생각했습니다:“상품 리스트를 가져오고, 브랜드/좋아요 정보를 붙이면 되지!”이 방식의 장점은 도메인 경계가 명확하다는 점이었습니다.Product는 ProductService에서Brand와 Like는 각각의 서비스에서 분리되어 처리하지만 정렬 기준이 다양해지면서 문제가 생겼습니다.예를 들어:좋아요 순 정렬브랜드 인기순 정렬주문/리뷰 기반 정렬 가능성기존 구조에서는 정렬을..

Loopers 2025.08.01

Loopers WIL – 2주차

1. 멱등성 – GET만 멱등하면 되는 게 아니었다처음엔 단순하게 생각했다.“GET은 멱등하고, POST는 멱등하지 않다.”하지만 좋아요 기능을 설계하면서 이 생각은 깨졌다.좋아요는 POST 요청이지만, 사용자가 100번을 눌러도 결과는 한 번만 반영되어야 한다.→ 이건 POST라도 비즈니스적으로는 멱등해야 한다.그제야 알게 됐다.HTTP 메서드의 특성만 따지는 게 아니라,**“이 요청이 시스템 상태를 얼마나 예측 가능하게 유지시켜주는가”**가 진짜 기준이라는 걸.이건 단순한 사용성 이슈를 넘어서 아래와 같은 시스템 설계로 이어진다:💥 동시성 제어🔁 재시도(Retry) 대응🔐 API 설계 시 신뢰성 확보결국 멱등성은 단순히 HTTP 개념이 아니라,서버의 신뢰성과 안정성을 지탱하는 설계 원칙이었다.?..

Loopers 2025.07.24

Loopers요구사항 정의서 없이 만드는 개발은 결국 돌고 돌아 제자리로 돌아온다

이번 주 루퍼스를 하며 가장 크게 느낀 건 이거였다.요구사항 정의서 없이 만드는 개발은 결국 돌고 돌아 제자리로 돌아온다.지금까지는 대부분 기획이 완료된 상태에서 기능만 구현해왔다.기획자가 기능 흐름을 정리해주면, 나는 필요한 객체를 떠올리고, DB 구조를 짠 다음 곧장 코딩에 들어갔다.그게 익숙했고, 딱히 문제라고 느끼지도 않았다.그런데 이번 과제는 달랐다.기획서 없이, 요구사항 정의부터 전부 직접 해야 하는 과제였다.🧱 전형적인 커머스니까 쉬울 줄 알았다주제는 커머스 서비스.로그인, 상품, 장바구니, 주문, 결제, 포인트 충전 등 익숙한 기능들이라처음엔 “쉬운 과제겠지” 싶었다. 그래서 초반엔 가볍게 접근했다.“로그인한 사용자만 접근 가능”, “재고 초과 시 주문 불가”, “없는 상품이면 에러” 같..

Loopers 2025.07.24

WIL – 1주차 (TDD & 테스트 가능한 구조)

이번 주는 TDD에 대한 부정적인 시선에서 출발했지만, 직접 겪어보면서 생각이 많이 바뀐 시간이었다. 단순히 테스트를 먼저 짠다는 개념이 아니라, 테스트가 설계를 밀어내는 도구라는 걸 처음으로 체감했다.특히 도메인 로직을 순수하게 유지하면 테스트가 자연스럽게 따라온다는 걸 경험했고, 반대로 설계가 엉키면 테스트도 어렵다는 걸 몸으로 느꼈다. 단위 테스트만 잘 짜면 되는 줄 알았는데, 테스트 가능한 구조 자체를 만드는 게 본질이라는 걸 배웠다.이번 주에 새로 배운 것테스트는 단순한 검증 수단이 아니라 설계를 유도하는 도구라는 사실도메인 모델을 정제하면 테스트 흐름도 깔끔해진다JPA Entity와 도메인 객체를 분리하고, Validation 책임을 도메인 계층으로 옮기는 실험FK 없이 연관관계를 관리하며 의..

Loopers 2025.07.17

TDD, 꼭 해야 해?

부정에서 시작한 Loopers 1주차 회고😵 도입 – ‘이게 맞나?’ 싶지만 해보기로 했다사실 나는 TDD에 부정적인 시선을 갖고 있다.할 줄은 안다. 하지만 “굳이 그걸 꼭 해야 하냐?”는 질문엔 여전히 확신이 없다.테스트 코드 짜는 데 들어가는 시간 대비 가성비가 너무 떨어진다고 생각했기 때문이다.이번 루퍼스 1주차 과제를 하면서도“왜 이걸 해야 하지?”라는 생각은 계속 들었다.하지만 _이유도 모르고 안 하는 것보단, 해보고 판단하자_는 마음으로 시작했다.부정적이었지만, 그래서 더 해보려 했다.❓ 시작 전, 내가 가졌던 고민들테스트 코드를 잘 짤 수 있을까?오랜만에 짜는 테스트, 내가 짜는 방식이 맞는 걸까?객체는 어떻게 설계해야 하지?‘테스트를 어떻게 잘 짤까?’보다는“언제, 어떤 흐름으로 짜야 ..

Loopers 2025.07.17

애플리케이션 배포 시 마주친 문제와 해결책

1. 인증 문제: Google OAuth2 403 Error 문제 상황 배포된 웹 애플리케이션에서 사용자가 Google 계정으로 로그인을 시도할 때, 403 Forbidden 에러가 발생했습니다. 원인 분석 오류 참조 링크를 통해 에러 확인 Google OAuth2는 등록된 리다이렉션 URL로만 사용자를 리다이렉트하도록 엄격하게 제한합니다. 개발 환경에서는 localhost로 설정된 리다이렉션 URL이 배포 환경의 URL과 다르기 때문에 인증 과정에서 문제가 발생했습니다. 해결 방법 Google Cloud Console 접속: Google Cloud Platform에서 제공하는 프로젝트 대시보드에 로그인합니다. OAuth2 클라이언트 ID 설정: 인증 정보 섹션에서 OAuth2 클라이언트 ID를 선택하고..

JPA: 양방향의 문제와 단방향의 해결책

JPA에서의 연관관계에 대한 고민 서론 JPA를 사용한 프로젝트에서 양방향 연관관계의 편리함과 동시에 발생하는 여러 문제들에 직면했습니다. 비록 프로젝트 규모는 작았지만, 연관관계가 많아지면서 발생한 복잡성과 순환 참조 문제는 실무의 더 큰 프로젝트에서 어떻게 확대될지 고민하게 했습니다. 이 포스트는 그 과정에서 겪었던 어려움, 그리고 이를 어떻게 극복했는지에 대한 회고입니다. 양방향 연관관계의 도입 처음에는 모든 연관관계를 양방향으로 구성했습니다. 이유는 간단했습니다: 데이터를 조회하고 관리하는 것이 편리했기 때문입니다. 하지만 이 선택이 가져온 복잡성과 순환 참조 문제는 예상치 못했던 도전이었습니다. //수정 전 USER 엔티티 @Entity @Table(name = "users") @Getter @..

[Spring , react] 실시간 채팅 구현하기

웹 기반 실시간 채팅의 핵심 기술 소개 WebSocket: 실시간 양방향 통신의 기반 정의: 웹 애플리케이션과 서버 간에 실시간, 양방향, 풀 듀플렉스 통신을 가능하게 하는 고급 통신 프로토콜입니다. 장점: 지속적인 연결을 통해 실시간 데이터 교환이 가능, HTTP 폴링에 비해 훨씬 효율적인 네트워크 자원 사용. 사용 예: 실시간 게임, 채팅 애플리케이션, 금융 시장 데이터 스트리밍. STOMP (Simple Text Oriented Messaging Protocol): 메시지 교환 프로토콜 정의: 간단한 텍스트 기반의 메시징 프로토콜로, 웹소켓 위에서 더 고급 메시징 기능을 제공합니다. 특징: 헤더와 바디를 포함하는 단순한 텍스트 메시지 형식을 사용. 구독/발행(pub-sub) 모델을 통해 특정 주제에..