전체 글

공부한 것 기록합니다
1. 쿠폰 발급 동시성 문제 발생 쿠폰 발급 데드락 문제 발생 (이전 글) 이전에 쿠폰 발급 동시성 테스트 중 데드락과 동시성 문제가 발생하였다!그런데 내가 처음에 집중하려던 것은 동시성 문제이기에 일단 `flush()`로 임시조치를 하고 다시 테스트를 실행해보았다. 실행 결과, 동시성 문제가 발생하였다!  발급된 쿠폰(`IssuedCoupon`)은 100개가 생성됐지만 쿠폰(`Coupon`)의 수량은 정상적으로 감소하지 않았다.이를 해결하기 위해 `비관적 락`을 도입하기로 했다. 1-1. 비관적 락을 선택한 이유락에는 `비관적 락`과 `낙관적 락`이 있다.`낙관적 락` 동시성 문제가 발생하지 않을 것이라 가정하여 동시성 문제가 발생했을 때 이를 처리하는 방식`비관적 락` 트랜잭션 충돌이 잦을 것이라 가..
1. 쿠폰 발급 로직과 데드락 문제 발생팀 프로젝트가 끝난 후 아쉬움이 남아, 쿠폰 기능을 따로 추출해 혼자 개발해보기로 했다.MySQL을 데이터베이스로 사용하고, 별다른 락을 걸지 않은 상태에서 쿠폰 발급 로직을 구현했다. 1-1. 쿠폰 발급 로직쿠폰 발급 로직은 다음과 같은 방식으로 작성했다.@Transactionalpublic Long issue(Long couponId, Long userId) { final Coupon coupon = validateCoupon(couponId); coupon.issue(QUANTITY_TO_ISSUE_COUPON); // TODO User 검증, 중복 검사 필요 final IssuedCoupon issuedCoupon = IssuedCoup..
· 공부
트랜잭션 격리 수준에 대해 공부하다가 Read Uncommitted와 Read Committed의 차이가 명확히 구분되지 않아 헷갈렸다. 그래서 더 깊이 공부한 뒤 다시 정리해 보기로 했다.Read Uncommitted- 가장 낮은 격리 수준이다. - 커밋되지 않은 데이터를 다른 트랜잭션에서 읽을 수 있다. - 성능은 좋지만, 데이터 일관성 보장 수준이 낮다. - `Dirty Read` 문제가 발생할 수 있다. Read Committed- 커밋된 데이터만 읽을 수 있다. - 하지만 한 트랜잭션이 데이터를 읽는 동안, 다른 트랜잭션이 동일 데이터를 수정하는 것을 방지하지는 못한다. - Dirty Read는 방지하지만, `Non-Repeatable Read` 문제가 발생할 수 있다.  처음에는 두 격리 수준..
· 공부
격리 수준- DB가 트랜잭션 간 동시 작업을 격리하는 수준 (level)- 동시에 여러 트랜잭션이 동일 컬럼, 로우, 테이블에 읽고 쓴다면?예상하지 못한 데이터 이상 현상 발생 → 동시성 문제데이터 정합성/무결성이 위배됨따라서 DB는 4단계 트랜잭션 격리 수준 제공 Read Uncommitted가장 낮은 격리 수준트랜잭션이 커밋되지 않은 데이터를 다른 트랜잭션에서 읽을 수 있음장점 성능이 가장 좋음단점 데이터 일관성 보장 수준이 가장 낮음 Read Committed트랜잭션 커밋된 데이터만 읽을 수 있음다른 트랜잭션이 데이터를 수정하면 문제가 발생한다........장점 Dirty Read 방지단점 Non-Repeatable Read 가능 - 동일한 데이터를 읽어도 값이 달라짐 Repeatable Read한..
작업 환경이 데스크탑에서 노트북으로 바뀌었다. 기존에 진행하던 작업을 이어가기 위해 임시 커밋을 만들어 원격 저장소에 푸시를 했다. 이후 노트북에서 푸시된 브랜치를 받아 작업을 이어갔지만, 임시 커밋은 더 이상 필요하지 않았다.  그래서 커밋 내역만 깔끔하게 제거하고 변경 사항은 유지하는 방법을 사용했다.  1. 임시 커밋 후 푸시 기존 작업을 잃지 않기 위해 모든 변경 사항을 임시로 커밋하고, 원격 저장소에 푸시를 했다. git add .git commit -m "temp: 임시 커밋"git push origin [브랜치명] 2. 다른 컴퓨터에서 브랜치 가져오기 노트북으로 작업 환경을 전환한 뒤, 푸시한 브랜치를 가져왔다. git pull origin [브랜치명] 이 과정을 통해 데스크탑에서 하던 작업..
프로젝트를 진행하면서 우리는 MSA 아키텍처 기반의 프로젝트이므로 다른 모듈에서 DTO를 참조할 수 있도록 각 서비스마다 DTO 모듈을 따로 만들어서 참조하도록 하였다.  그런데 order 서비스의 server 모듈과 dto 모듈에서 서로를 참조하게 되었는데, 오류가 났다! `순환 종속성` 때문에 난 오류였다. 이를 해결하기 위해 서로에 대한 의존성을 제거해야 했다. 서로를 참조하게 된 이유는, 이런 식으로 dto 모듈에 있는 DTO들을 Order 객체를 받아서 만들기 위해 참조한 것이었다. public static NotificationOrderDto from(Order order, String displayProductName) { return new NotificationOrderDto(ord..
배포 흐름도 코드 작성개발자가 로컬에서 애플리케이션 코드 작성 및 수정코드 푸시코드를 GitHub 리포지토리의 특정 브랜치에 푸시GitHub Actions 트리거코드 푸시 시 GitHub Actions가 자동으로 트리거됨CI/CD 파이프라인 실행 (GitHub Actions)빌드 단계애플리케이션 빌드자코코 테스트 커버리지 측정자코코를 사용하여 테스트 코드의 커버리지 측정커버리지 리포트를 생성하여 품질 확인테스트 실행빌드 아티팩트 생성Docker 이미지 빌드Dockerfile을 사용해 애플리케이션의 Docker 이미지 생성ECR에 Docker 이미지 푸시 (도커 허브 개념)빌드된 Docker 이미지를 AWS Elastic Container Registry (ECR)로 푸시ECS에 배포 - 컨테이너 관리, ..
이번에 MSA 프로젝트를 진행하면서 각 서비스끼리 `FeignClient`를 통해 호출하는 경우가 많았다. 그 중 배송담당자 CRUD 기능을 구현하는 과정에서 FeignClient의 N+1 호출 문제가 발생하게 되었다. 이를 해결한 방법을 기록해보려고 한다. 1. 배송담당자 전체 조회 기능 구현마스터 관리자는 배송담당자 목록을 전체 조회할 수 있어야 했다.1.1 배송담당자 도메인 설계배송담당자는 특정 허브에 속할 수 있기 때문에, 배송담당자와 허브는 `다대일 관계`로 설계했다. 하지만 MSA 아키텍처를 사용하므로, 객체 자체로 연관관계를 매핑하는 대신 `간접 참조`를 사용해 Hub ID만 Shipper 도메인에 넣어주었다.@Getter@Entity@Table(name = "p_shipper")@NoArg..
린구
린구의 개발자 되기