티스토리챌린지 6

[Spring Boot] 동시성 제어 (4) - Redis

** 본 글은 인프런 재고시스템으로 알아보는 동시성이슈 해결방법> 을 수강한 후 작성한 글입니다.동시성 문제 해결 방법 3. RedisLettucesetnx 명령어를 활용하여 분산락 구현spin lock 방식: 락을 획득하지 못한 경우 락을 획득하기 위해 계속 요청을 보낸다.별도의 retry 로직 작성이 필요하다.Redissonpub/sub 방식: 채널을 하나 만들고 락을 점유 중인 스레드가 락을 획득하려고 대기 중인 스레드에게 해제를 알려주면, 안내를 받은 스레드가 락 획득을 시도한다.별도의 retry 로직 작성이 필요하지 않다.Redis 설치docker pull redisdocker run --name myredis -d -p 6379:6379 redisLettuce를 이용하여 재고 감소 로직 작성하..

*/Spring 2024.11.12

[Spring Boot] 동시성 제어 (3) - Database

** 본 글은 인프런 재고시스템으로 알아보는 동시성이슈 해결방법> 을 수강한 후 작성한 글입니다.동시성 문제 해결 방법 2. DatabaseMySQL 활용Pessimistic Lock실제로 데이터에 Lock을 걸어 정합성을 맞추는 방법데드락이 걸릴 수 있다.Optimistic Lock실제로 Lock을 사용하지 않고 버전을 이용함으로써 정합성을 맞추는 방법먼저 데이터를 읽은 후에 update를 수행할 때 현재 내가 읽은 버전이 맞는지 확인하며 업데이트Named Lock이름을 가진 metadata locking이름을 가진 Lock을 획득한 후 해제할 때까지 다른 세션은 이 Lock을 획득할 수 없도록 한다.트랜잭션이 종료될 때 Lock이 자동으로 해제되지 않기 때문에 별도의 명령어로 해제를 수행해주거나 선점..

*/Spring 2024.11.11

[Spring Boot] 동시성 제어 (2) - Synchronized

** 본 글은 인프런 재고시스템으로 알아보는 동시성이슈 해결방법> 을 수강한 후 작성한 글입니다.동시성 문제 해결 방법 1. SynchronizedSynchronized자바의 Synchronized 를 이용해보자.Synchronized 를 메서드 선언부에 붙여주면 해당 메서드는 한 개의 스레드만 접근이 가능하게 된다. @Transactionalpublic synchronized void synchronizedDecrease(Long id, Long quantity) { // Stock 조회 Stock stock = stockRepository.findById(id) .orElseThrow(() -> new RuntimeException("Stock을 조회할 수 없습니다.")..

*/Spring 2024.11.10

[Spring Boot] 동시성 제어 (1) - 동시성 문제, 재고 감소 시스템 구현 및 테스트

** 본 글은 인프런 재고시스템으로 알아보는 동시성이슈 해결방법> 을 수강한 후 작성한 글입니다.동시성 문제를 해결하지 않으면?Race Condition!→ 두 개 이상의 프로세스가 공통 자원을 병행적으로(concurrently) 읽거나 쓰는 동작을 할 때, 공용 데이터에 대한 접근이 어떤 순서에 따라 이루어졌는지에 따라 그 실행 결과가 같지 않고 달라지는 상황재고 감소 시스템 구현 및 테스트재고 감소 로직 작성엔티티 생성 package com.example.stock.domain; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; impo..

*/Spring 2024.11.09

[JPA] 엔티티 equals 메서드 구현 시 주의할 점

개발 진행 중, 프론트 분께 아래와 요청을 받았다.해당 내용을 확인해보니, Member에 equals 메서드를 이렇게 구현하고 있었다.@Overridepublic boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Member member = (Member) o; return Objects.equals(idMember, member.idMember);}프린트 찍어보니까하나는 프록시 객체라서 false를 반환했던 것..!그래서 하이버네이트 객체의 클래스를 불러오도록 수정해줬다.@Overridepublic boolean equals(Ob..

*/Spring 2024.11.08

[JPA] Join Fetch 시 MultipleBagFetchException

문제프로젝트를 진행하다가org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags이런 에러가 떴다.원인하나의 Member 엔티티에서@OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)private List profileImages;@OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)private List fevers;두 개의 OneToMan..

*/Spring 2024.11.07