본문 바로가기

Java5

[Java / Spring Boot] 브랜드에서 전화가 왔다, "우리 상품 좋아요가 한번에 수십개씩 빠져요!" - 5편 좋아요 카운트 로직을 짜다가 문제를 발견했다."약간의 오차는 괜찮다"고 판단하고 비동기로 처리했는데, 코드를 들여다보니 수십 개씩 틀어질 수 있는 구조였다.실제로 운영 중에 이런 상황이 생기면 어떻게 될까? 가상의 브랜드 담당자에게 "좋아요 수가 갑자기 수십 개씩 줄었다가 돌아와요"라는 연락을 받는다고 상상해보자. 처음엔 식은땀이 날 것 같다. "약간의 오차는 괜찮다"고 했는데, "약간의 오차"와 "수십 개씩 튀는 것"은 달랐다.원인을 찾아보자.정규화 vs 비정규화좋아요 수를 보여주는 가장 자연스러운 방법은 이거다.SELECT COUNT(*) FROM likes WHERE product_id = 1이게 정규화 방식이다. 데이터를 중복 없이 한 곳에만 저장하고, 필요할 때 계산한다.정규화:장점 → 데이터 .. 2026. 3. 6.
[Java / Spring Boot] 쿠폰 사용에 대한 처리는 어떤 락이 적절할까 - 4편 3편 마지막에 이런 질문을 던졌다.(3편: 비관적 락 vs 낙관적 락, 선택 기준은 무엇이었나 - 3편)유니크 키는 어디에 쓰는 걸까?쿠폰 로직을 구현하면서 답을 찾았다.재고 vs 쿠폰: 충돌 패턴이 다르다재고는 여러 사람이 하나를 두고 경쟁하는 문제다. 쿠폰은 다르다.재고 차감: 불특정 다수가 동시에 같은 상품에 달려듦쿠폰 발급: 동일 사용자의 중복 요청이 문제쿠폰 사용: 같은 쿠폰으로 동시에 두 번 주문 시도충돌 주체가 다르니까 전략도 달라야 한다.쿠폰 중복 발급: DB 유니크 키로 막는다애플리케이션 코드에서 이렇게 체크하면 충분할 것 같다.@Transactionalpublic void issue(Long userId, Long couponId) { boolean exists = us.. 2026. 3. 6.
[Java / Spring Boot] 비관적 락 vs 낙관적 락, 선택 기준은 무엇이었나 - 3편 2편에서 재고 차감에 비관적 락을 적용했다. 그런데 모든 상황에 비관적 락이 정답은 아니다.(2편: 스투시 반팔티를 10명이 동시에 주문했을 때 발생한 일-2편 )비관적 락은 하나씩 순차 처리라 병목현상이 생기고, 데드락 위험도 있다.충돌이 거의 없는 상황에서도 락을 걸면 비용만 크고 얻는 게 없는 상황이 된다.충돌 빈도가 다르다재고 차감: 불특정 다수가 동시에 같은 상품에 달려듦 → 충돌 빈도 높음게시글 수정: 보통 작성자 혼자 수정 → 충돌 빈도 낮음게시글 수정에 비관적 락을 걸면 어떻게 될까?작성자가 수정 버튼 클릭→ SELECT FOR UPDATE (배타 락 획득)→ 수정 폼에서 내용 입력 중... (30초)→ 저장 클릭 → 커밋 → 락 해제이 30초 동안 배타 락이 걸려있다. 다른 사람들은 .. 2026. 3. 6.
[Java / Spring Boot] 스투시 반팔티를 10명이 동시에 주문했을 때 발생한 일-2편 배경재고가 1개뿐인 상품에 10명이 동시에 주문을 넣었다.결과는 10명 전부 주문 성공이었다. 에러도 없이. 재고는 -9가 됐다. 음.....?뭐가 문제인지 보기 전엔 몰랐다재고 차감 코드는 단순해 보인다.@Transactionalpublic void order(Long optionId, int quantity) { Stock stock = stockRepository.findByOptionId(optionId); // 1. 재고 읽기 if (stock.getQuantity() @Transactional도 붙어있고, 재고 확인도 하고 있으니 괜찮은 거 아닌가?문제는 2번 재고 확인 시점에서 생긴다.왜 이런 일이 생기나: Lost Update10개 트랜잭션이 동시에 실행될 때 실제로 어떤 일이 .. 2026. 3. 6.
반응형