성장일기

내가 보려고 정리하는 공부기록

전체 글 219

[아키텍처] 아웃박스 패턴으로 DB와 외부시스템 정합성 문제를 해결할 수 있을까?

알림 개발을 하면서 FCM을 사용했는데, 한 가지 질문을 마주했다. DB에 알림을 저장하는 것과 실제 외부API로 알림을 발송하는 것이 원자적으로 동작하는가? 알림 발송이 내부 동작이라면 트랜잭션으로 원자적으로 묶을 수 있다. 알림 발송이 실패하더라도 롤백되기 때문에 정합성이 보장되는데, 실제 알림 발송은 외부 시스템을 사용하기 때문에 이 방식으로는 원자성을 보장할 수 없다. 여기서 나온 패턴이 바로 아웃박스 패턴이다. 해당 게시글에서 이 아웃박스 패턴에 대해 정리해보려고 한다. 문제상황 실제 알림을 발송하는 상황을 예로 들어 살펴보자.@Transactionalpublic void createOrder(OrderRequest request) { Order order = orderRepository..

[네트워크] Websocket을 사용해야 하는 이유 - 채팅 엔진 구현기

채팅을 구현해야 할 때면 항상 따라붙는 단어였던 Websocket에 대해 정확하게 이해하고자 정리해보려고 한다! 목차는 다음과 같다.Websocket이 필요한 이유HTTP의 한계websocket이란?websocket이 없을 때 실시간 서비스Websocket의 통신방법Websocket의 문제점STOMP란스프링에서 STOMP 기반 웹소켓 구현하기 Websocket이 필요한 이유웹소켓은 실시간성 서비스에 필요하다는 걸 모두 알고있을 것이다. 즉, HTTP가 실시간 지원이 불가능하기 때문에 웹소켓을 사용하는 것이다. HTTP는 어떤 방식으로 동작할까? HTTP의 동작방식HTTP는 요청/응답 (request-response) 모델을 기반으로 하는 프로토콜이다. 통신의 흐름이 언제나 클라이언트의 요청에서 시작되고,..

CS 2026.08.29

[Spring] 요청을 보내면 어떤 일이 벌어질까? : 트랜잭션과 DB 커넥션

프로젝트를 진행하다보면 당연하게 transaction 어노테이션을 사용한다. 트랜잭션을 쓰는 이유라고 한다면 성공하면 전체 성공, 실패하면 전체 롤백을 하는 방식으로 원자성을 확보하기 위함인게 가장 크다고 생각한다. 이렇게 얄팍하게 알고있던 트랜잭션을 정리해보려고 한다. 목차는 다음과 같다. 트랜잭션을 사용하는 이유트랜잭션의 전파 레벨과 DB커넥션요청이 들어온다면 어떤일이 벌어질까? 1. 트랜잭션을 사용하는 이유트랜잭션을 사용하는 이유는 앞서 말했던 원자성 확보도 있지만, 다른 이유들이 있다. 트랜잭션을 사용함으로써 보장되는 4가지가 있는데 이를 ACID라고 한다. ACID 원자성 (Atomicity): 트랜잭션 안의 모든 작업은 전부 성공하거나 전부 실패한다. 하나라도 실패하면 나머지도 전부 되돌린다..

백엔드/스프링 2026.07.20

[DB] 낙관적 락과 비관적 락에 대하여

데이터베이스를 다룰 때, 운영체제를 배웠을 때 등 공부하다보면 락(lock)이라는 개념을 자주 마주한다. 상황에 따라 낙관적 락과 비관적 락이라는 개념이 등장하는데 얄팍하게 알고있던 이 개념을 한 번 정리해 보려고 한다. 목차는 아래와 같다. 락이 필요한 이유낙관적 락과 비관적 락, 각각이 무엇이고 무엇을 써야할까Spring에서 락 구현하기1. 락이 필요한 이유아래와 같은 상황이 생겼다고 해보자. 주문 A가 재고를 읽습니다 → "10개네"주문 B도 재고를 읽습니다 → "10개네"주문 A가 1개 팔고 저장합니다 → "9개로 줄여야지"주문 B도 1개 팔고 저장합니다 → "9개로 줄여야지"실제로는 2개가 팔렸으나, 결과적으로 재고는 9개가 된다. 실제 서비스에서 이런 오류가 발생한다면 꽤 치명적일 것이다. 이..

백엔드 2026.06.30

[Spring/테스트] N+1을 테스트 코드로 막아본다면 - 쿼리 카운트 테스트 도입기

N+1은 보통 사후에 발견된다. 더미데이터를 잔뜩 넣고 API 테스트를 하는 도중에 너무 느려서 발견한다던가, 코드리뷰로 발견한다던가 보통 그런식으로 발견해왔다. 물론! 처음부터 N+1이 발생하지 않도록 구현하는게 가장 좋겠지만, 놓칠때도 종종 있다. 요즘은 AI로 코드를 짜는 일이 훨씬 많기 때문에, 더더욱 놓칠때가 많았다. 한 번 fetch join으로 고치고 나서도, 누군가가 연관 엔티티를 lazy하게 건드리는 코드를 추가하면 또다시 N+1이 발생한다. 이런 문제를 겪다보니 문득 테스트코드로 만들면 CI를 돌릴 때 잡을 수 있지 않을까? 하는 생각을 하게 되었다. 로직을 짤 때 쿼리가 몇 번 나가는지를 안다면 수를 비교해서 N+1 발생을 인지할 수 있다. 쿼리가 나가는 수는 Hibernate에서 ..

백엔드/스프링 2026.06.18

[JPA] @OneToOne LAZY의 함정 - N+1 해결하기

작년에 시작한 프로젝트를 최근 리팩토링 하기 시작했다. 지금도 감자지만 더더욱 감자일 때 작성한 코드다 보니, 리팩토링 할 부분이 많았고 오늘은 찜 관련 기능의 리팩토링을 진행했다. 우리 프로젝트에선 모임과 운동을 찜할 수 있었고, 각각의 찜 목록 조회에서 N+1 문제가 있어서 이를 해결하는 게 목적이었다. 문제의 발견N+1을 해결하기 위해 주로 fetch join을 사용해왔고, 찜과 관련한 눈에 보이는 연관 객체들을 fetch join으로 한 번에 가져오도록 수정했다. 그러고 쿼리 카운트 테스트를 돌렸는데 실패했다. N+1문제가 해결되지 않았다는 뜻이었다.북마크 찜 목록 N+1 회귀 테스트 > 찜한 운동 목록 - 찜 개수와 무관하게 고정된 쿼리 수만 실행한다 FAILED북마크 찜 목록 N+1 회귀 테..

백엔드/스프링 2026.06.17

[DB] 쿼리 튜닝은 무엇인가 (3) - 복합 인덱스에서 순서가 중요한 이유

지난 게시글에서는 B-tree와 B+tree가 어떤 원리인지를 배웠고, 키를 정렬된 순서로 보관한다는 것도 배웠다. https://wanna-developer02.tistory.com/219 [DB] 쿼리 튜닝은 무엇인가 (2) - 인덱스 (B-tree와 B+tree)지난 게시글에서는 쿼리 튜닝이 무엇인지에 대해 다루었고, 이번 게시글에서는 인덱스에 대해 이어서 정리하려고 한다. 지난 게시글은 아래 링크를 참고하면 된다.https://wanna-developer02.tistory.com/2wanna-developer02.tistory.com 이번 게시글에서는 칼럼 여러개를 묶어 하나의 인덱스로 만들면 어떻게 될지 알아보려 한다. 목차는 다음과 같다.복합 인덱스란칼럼 순서를 정하는 방법 1. 복합 인덱스란..

카테고리 없음 2026.06.08

[DB] 쿼리 튜닝은 무엇인가 (2) - 인덱스 (B-tree와 B+tree)

지난 게시글에서는 쿼리 튜닝이 무엇인지에 대해 다루었고, 이번 게시글에서는 인덱스에 대해 이어서 정리하려고 한다. 지난 게시글은 아래 링크를 참고하면 된다.https://wanna-developer02.tistory.com/218 [DB] 쿼리 튜닝은 무엇인가 (1) - 랜덤 I/O와 쿼리 튜닝프로젝트를 진행하면서 조회 성능을 올리기 위해 인덱스를 건 적이 있다. 어떨 때는 성능이 개선되지만, 어떨 때는 오히려 성능이 안 좋아지기도 한다. "인덱스를 많이 걸면 성능이 저하된다" 라wanna-developer02.tistory.com 인덱스는 점프를 통해 데이터의 위치를 찾아내는데 그 원리는 무엇인지에 대해 정리해볼 예정이다. 목차는 다음과 같다.정렬배열과 이진 탐색의 한계B-tree 와 B+tree 클러..

데이터베이스 2026.06.08

[DB] 쿼리 튜닝은 무엇인가 (1) - 랜덤 I/O와 쿼리 튜닝

프로젝트를 진행하면서 조회 성능을 올리기 위해 인덱스를 건 적이 있다. 어떨 때는 성능이 개선되지만, 어떨 때는 오히려 성능이 안 좋아지기도 한다. "인덱스를 많이 걸면 성능이 저하된다" 라는 이야기를 많이 들어봤는데, 그 이유가 무엇인지 정리해보려고 한다. 목차는 아래와 같다.순차 I/O vs 랜덤 I/O쿼리 튜닝이란 무엇인가인덱스가 성능을 저하시키는 경우에 대하여 1. 순차 I/O vs 랜덤 I/O결론적으로 조회 성능은 "몇 행을 읽었는가" 보다는 "디스크에 점프를 몇 번 했는가"로 결정된다. 디스크는 데이터를 물리적으로 연속된 블록 단위로 저장하는데, 데이터를 읽기 위해서는 그 위치로 이동해야한다. 이때 나오는 개념이 순차 I/O와 랜덤 I/O이다. 순차 I/O물리적으로 인접한 블록을 연속해서 ..

데이터베이스 2026.06.07

[시큐리티] 세션과 JWT의 비교와 보안 취약점 알아보기

회원가입과 로그인을 구현하는 과정에서 인증 처리를 하는 방식에는 크게 세션방식과 토큰방식(JWT)이 있다. 대부분 프로젝트에서는 JWT를 사용하는 것을 많이 봤고, 나 또한 JWT를 사용했었다. 문득 JWT가 더 선호되는 이유가 궁금해져 세션과 토큰방식의 차이점을 정리해보려고 한다. HTTP는 기본적으로 무상태(stateless) 프로토콜이기 때문에, 서버는 방금 요청을 보낸 사람을 기억하지 못한다. 로그인이라는 기능은 본질적으로 이 사용자가 누구인지 계속 기억하고 있어야 성립하기 때문에, 상태를 유지해야 한다. 상태를 유지하는 방식 중 하나가 세션과 JWT 방식이다. ✅ 세션과 JWT 비교세션 방식 세션방식은 서버에서 사용자의 상태를 저장해두고, 클라이언트에게는 그 정보를 가리키는 무의미한 식별자만 ..