
[Spring] JPA OptimisticLock은 락을 잡지 않는가?
2025. 3. 9. 13:20
Spring/JPA
0. 들어가며JPA를 활용하여 애플리케이션을 개발하다 보면 동시성 문제를 해결하기 위해 낙관적 락(Optimistic Lock)을 적용하는 경우가 있습니다. @Version 애노테이션을 사용하면 간단하게 해결되는 것처럼 보이지만, 흔히 낙관적 락을 "락을 걸지 않는다"고 표현하기 때문에 실제로 MySQL에서 어떻게 동작하는지 궁금해졌습니다. MySQL에서 UPDATE 문을 실행할 때는 반드시 락을 획득해야 하는데, 그렇다면 JPA의 낙관적 락은 어떻게 "락 없이" 동작하는 것일까요? 이에 대한 궁금증을 해결하기 위해 찾아본 내용을 정리해보았습니다. 결론적으로, JPA의 낙관적 락은 애플리케이션 차원에서 제공하는 충돌 감지 메커니즘이며, MySQL에서는 UPDATE 수행 시 실제로 락을 거는 것이 맞습니다..

[Spring] Cache Stampede 문제를 해결하는 Two-Level-TTL-Cache 구현
2025. 1. 11. 14:28
Spring
들어가며.캐시 만료 시점에 모든 요청이 DB를 찌르게되어 부하가 발생하는 문제인 Cache Stampede는 개발을 할 때 주의해야하는 사항 중 하나이다. 관련 내용은 아래 글에 잘 나와있다. 캐시 문제 해결 가이드 - DB 과부하 방지 실전 팁대용량 트래픽 환경에서 캐시를 사용할 때 주의해야할 위험 상황과 예방법을 소개합니다.toss.tech Cache Stampede를 해결하는 방식 중 분산락을 사용하는 방식이 있고, 그 중 가장 쉽게 생각할 수 있는 방식은 다음과 같다.캐시가 만료되면 캐시 갱신에 대한 Lock을 획득한 요청이 캐시를 갱신하고 다른 요청들은 대기하는 구조로 만든다.Lock을 획득한 요청이 캐시를 갱신하면 다른 요청들이 캐시를 읽는다.하지만 이렇게 만들게 되면 Lock을 획득한 요청..

스프링 부트는 어떻게 라이브러리 버전 관리를 자동으로 하지?
2024. 12. 12. 20:55
Spring
0. 들어가며스프링부트로 개발을 하다보면 다양한 외부 라이브러리를 활용하게 됩니다. 예를 들어, 웹 애플리케이션을 위해 spring-boot-starter-web을, DB 연동을 위해 spring-boot-starter-data-jpa를, JSON 처리를 위해 jackson 계열 라이브러리를 사용하죠.그런데 스프링부트를 사용하면 특정 라이브러리의 버전을 적지 않아도 프로젝트가 잘 빌드되고 동작합니다. 스프링부트는 의존성을 관리해주는 기능을 제공하는데, 어떻게 라이브러리 버전을 자동으로 관리하는지 궁금하여 알아본 내용을 글로 정리합니다. 1. 스프링 부트와 의존성 관리1.1 의존성 관리의 필요성프로젝트를 진행하다보면 수많은 라이브러리를 가져다 쓰게됩니다. 하나의 웹 애플리케이션을 개발한다고 해도 적어도 다..

Private Method를 테스트를 하고싶으면 어떡하지?
2024. 12. 4. 21:40
Spring
0. 서론NEXT STEP TDD 수업을 들으며 기능을 구현하던 와중 private method를 테스트하고 싶다는 생각이 들었는데요. private method를 테스트하면 좋지 않다고 들어왔기 때문에 멈칫하게 되었고, 이에 정말 private method 는 테스트하면 안좋은걸까라는 의문이 생겨서 이 글로 제 개인적인 의견을 정리해봅니다. 1. private method를 테스트하는 것이 왜 좋지 않은가?여러 자료를 살펴보면 private method를 테스트하는 것이 변경에 취약한 구조를 만든다고 합니다. 이에 대한 이해를 위해 public method와 private method의 변경 가능성에 대한 전제 하나를 만들고 가야하는데요. public method는 클래스 외부에 공개된 계약으로 간주됩..

[JPA] findByXXX 와 findByXXXId 에서 생기는 차이
2023. 8. 5. 00:47
Spring/JPA
0. 문제상황 🤔 Spring Data JPA를 사용하다가 다음과 같은 상황이 있었습니다. A 라는 엔티티가 B 라는 엔티티를 필드로 가지고 있는데 A를 찾기 위해 B 조건을 걸고 싶었던 것이죠. 원래 같았으면 findByB(B b) 와 같은 메서드를 Spring Data JPA를 사용해 추가했을 텐데 제약사항때문에 findByBId(Long id)와 같이 B의 Id 값을 통해 불러오고 싶었습니다. 근데 왠걸 findByBId(Long id)를 호출하고 쿼리를 확인해보았더니 join문이 끼어있더군요. 이런 상황이 왜 벌어졌는지 알아보았고, 이를 알아본 내용을 정리하려합니다. 1. 테스트 해보기❗️ 우선 상황을 가정해보도록 하겠습니다. 아래와 같이 Member 엔티티와 Team 엔티티가 있다고 생각해봅시다..

[Spring] 동시성 이슈 해결하는 방법 찍먹하기
2023. 7. 22. 18:30
Spring
0. 들어가며 🏃🏻♂️ 평소 동시성 이슈에 대해 알고는 있었으나, 이를 어떻게 해결하는지 이론적으로만 알고 있다고 생각하여 코드상으로는 어떻게 구현할 수 있는지에 대해 알아보기 위해 공부하였고, 이에 대한 내용을 정리해보려합니다. 전체적으로 인프런의 재고시스템으로 알아보는 동시성이슈 해결방법 강의를 참고하였습니다. 1. 전체 개요 📖 우선 글에서 가정이 되는 상황을 먼저 소개하겠습니다. 어떤 물품을 판매한다고 가정했을 때 물품의 수량이 있을 것이고, 소비자가 물품을 사는 행위를 할 때마다 Stock entity에 decrease 메서드를 통해 수량을 감소시키는 간단한 상황을 생각해보겠습니다. @Entity public class Stock { private Long quantity; public voi..

[Spring & Java] 왜 난 개발할 때 Runtime Exception을 써왔지?
2023. 5. 16. 14:53
Spring
0. 들어가며 🏃🏻♂️ 스프링으로 개발을 하다 보면 예외에 대한 코드를 작성하는 경우가 많이 있습니다. 예외처리를 위해 커스텀 예외 클래스를 종종 만들곤 했는데 대부분의 경우 RuntimeException을 상속받아 클래스를 작성했습니다. 이러한 방법에 불편함이 없었기 때문에 별생각 없이 쓰고 있다가 문득 나는 왜 개발할 때 Checked Exception이 아닌 Unchecked Exception 즉, Runtime Exception을 주로 사용했지라는 물음에 답을 할 수 없음을 깨달았습니다. 이에 해당 내용을 공부해 보았고, 공부한 내용을 정리해보려 합니다. 1. Java의 Exception 간단한 복습 📖 본격적으로 글을 쓰기 전에 먼저 Java에서의 Exception에 대해 간단히 내용정리를 해..

[Spring] 의존성 주입과 의존성 주입 방법에 대하여.
2023. 4. 30. 16:43
Spring
0. 들어가며 🏃🏻♂️ Spring을 사용하며 객체간의 의존성을 주입할때 생성자 주입을 권장한다는 이유를 듣고는 이를 별생각없이 사용해왔습니다. 이번 글을 통해 의존성 주입 방법에는 무엇이 있고, 생성자 주입에는 어떤 장점이 있길래 이를 권장하는지 알아보도록 하겠습니다. 1. 의존성 주입이란❓ 의존성 주입 방법에 대해 알아보기 전 간단하게 의존한다는 것은 무엇인지 그리고 의존성 주입이 무엇인지에 대해 알아보도록 하겠습니다. A가 B에 의존한다라는 것은 B가 변할 때 A에 영향이 미친다는 것과 같은 말입니다. 한 예로 A가 B의 특정 메소드를 사용한다고 하면 B의 특정 메소드 내부 기능이 변할 때 A에 영향을 미치게 되겠죠. 혹은 B의 특정 메소드 형식이 바뀌면 A에 영향을 미치게 되는 것이 또다른 예시..

[Spring] Spring MVC는 어떻게 요청에 응답할까? (Dispatcher Servlet을 중심으로)
2023. 3. 16. 03:47
Spring
0. 들어가며 🏃🏻♂️ 스프링 MVC를 사용하면 클라이언트에 요청에 따라 적절한 응답을 만들어낼 수 있습니다. 그 과정을 대략적으로나마 알고있었지만 이를 좀 더 명확하게 정리하는 시간을 가지고자 Dispatcher Servlet을 중심으로 스프링이 어떤 방식을 사용해 요청에 응답하는지 알아보도록 하겠습니다. 1. Spring MVC Cycle을 Dispatcher Servlet과 함께 살펴보기 😀 위 그림은 Spring MVC 구조입니다. 실제로는 Dispatcher Servlet에 요청이 들어가기 전 필터를 거치는데 이 부분은 생략되어 있습니다. 처음 볼때는 한눈에 잘 들어오지 않는 구조라 구조의 중심이 되는 Dispatcher Servlet 내부를 살펴보며 한단계 한단계 살펴보도록 하겠습니다. 0...

[Spring & Project] 소셜로그인 기능에 전략 패턴을 적용하기
2023. 2. 18. 03:44
Spring/Project
0. 들어가며🏃🏻♂️ 진행했던 프로젝트에서 구글과 카카오 소셜로그인 기능을 구현했었는데 해당 코드를 다시 살펴보며 리팩토링하면 좋겠다 싶은 부분을 발견했습니다. 이번 글에서는 디자인 패턴 중 하나인 전략 패턴(Strategy Pattern)을 적용해 리팩토링해본 경험을 정리해보려 합니다. 1. 기존의 코드는..🤔 기존 코드에서는 구글 로그인과 카카오 로그인을 각각 다른 API로 처리하였습니다. 간략하게 아래와 같은 형태였죠. @GetMapping("/google/login") fun googleLogin(...) { 구글 로그인... } @GetMapping("/kakao/login") fun kakaoLogin(...) { 카카오 로그인... } 기능은 잘 동작했지만, 거의 같은 기능을 하는 API가..