[Index-8][Optimization] FullText Index와 n-gram 파서
·
Database/MySQL
1. 문제 발견: LIKE 검색의 치명적 성능 한계1.1. 문제 인식: 4초짜리 검색 대기 시간 100만 개 이상의 상품 데이터가 누적된 환경에서 상품명 검색 기능에 심각한 병목 현상이 발생했다. 특히 `item-performance.http`를 통해 아래의 요청을 실행했을 때, 응답 시간이 3,927ms(약 4초)를 기록하며 사용자 경험을 심각하게 저해하는 수준임을 확인했다.대상 요청: GET http://localhost:8000/items?title=Mock 상품 제목 10&page=0&size=201.2. LIKE 검색의 구조적 결함 (기존 코드 분석) 문제의 근본 원인은 ItemRepositoryImpl.java에서 QueryDSL의 .contains() 메서드를 사용한 방식에 있었다.// 기존..
[Lock-10][Optimization] Lock: 실무 적용(⭐) - 트랜잭션 범위 축소와 이벤트 기반 관심사 분리
·
Database/MySQL
1. 들어가며 이전 시간까지 데이터베이스 내부의 락(Lock)을 활용하여 동시성을 제어하는 방법을 학습하였다. 하지만 실제 서비스는 데이터베이스 작업만으로 끝나지 않는다. 현실의 비즈니스는 외부 티켓 예매 시스템(인터파크 등)과 통신해야 하며, 예약 완료 후 사용자에게 알림톡을 발송하는 등 수많은 외부 연동을 포함한다. 이러한 외부 API 호출이 트랜잭션과 얽힐 때 어떤 성능 저하와 장애를 유발하는지, 그리고 이를 어떻게 구조적으로 개선할 수 있는지 상세히 살펴보고자 한다.2. [요구사항 1] 외부 API 호출과 거대 트랜잭션의 위험성콘서트 예약 시 좌석 정보를 DB에 저장한 후, 외부 티켓 예매 시스템에 등록하고 카카오톡 알림을 발송해야 하는 상황을 가정한다. 외부 API들은 네트워크 상태에 따라 각각..
[Lock-9][Optimization]네임드 락(Named Lock)의 구현과 트랜잭션 분리 및 성능 최적화
·
Database/MySQL
1. 네임드 락(Named Lock)이란? 네임드 락(Named Lock)은 MySQL에서 제공하는 GET_LOCK() 및 RELEASE_LOCK() 함수를 사용하여 사용자가 지정한 임의의 문자열에 대해 잠금을 획득하는 기능이다. 기존의 레코드 락(X-Lock, S-Lock)이 특정 데이터 행을 잠근다면, 네임드 락은 "유저의 주문", "이벤트 응모"와 같이 특정 '행위'나 '논리적 리소스'를 잠글 수 있다는 점이 특징이다. 이는 데이터베이스 레벨에서 제공하는 락이기에 분산 환경에서도 효과적인 동시성 제어가 가능하다.장점: 별도의 인프라(Redis 등) 없이 분산 환경에서 동시성 제어 가능데이터베이스 레벨의 강력한 정합성 제공특정 리소스 식별자(문자열) 기반의 유연한 관리단점: 락 획득 및 해제를 명시적..
[Lock-8][Optimization] 비관적 락(Pessimistic Lock)과 낙관적 락(Optimistic Lock) 구현 및 비교
·
Database/MySQL
1. 들어가며 데이터베이스 동시성 문제를 해결하는 대표적인 전략으로 낙관적 락(Optimistic Lock)과 비관적 락(Pessimistic Lock)이 존재한다. 두 방식의 핵심적인 차이는 충돌을 사전에 방지할 것인지(비관적), 아니면 발생한 후에 처리할 것인지(낙관적)에 있다. 본 포스팅에서는 각 락의 개념과 Spring Data JPA를 이용한 구현 방법, 그리고 효율적인 운영을 위한 디자인 패턴에 대해 서술한다.2. 비관적 락 (Pessimistic Lock)비관적 락은 데이터 수정 전 해당 데이터에 대한 접근을 명시적으로 제한하는 방식이다. 충돌이 빈번하게 발생할 것이라고 가정하고, 미리 배타적인 권한을 확보함으로써 데이터의 일관성을 강력하게 유지한다.2.1. 구현 방식 비관적 락은 배타 락(..
[Lock-7][Optimization] 데드락(Deadlock)의 유령과 갱신 분실(Lost Update)의 함정
·
Database/MySQL
1. 들어가며 전국민이 사랑하는 아이유의 콘서트가 열린다고 가정해보자. 좌석은 단 100석(maxParticipants). 이 티켓을 차지하기 위해 수만 명의 관객(Member)이 동시에 접속 버튼을 누른다. 우리의 시스템은 간단하다. 관객이 예매 버튼을 누르면 다음 두 가지 일이 순차적으로 일어난다.티켓 발급: EventParticipant(티켓) 테이블에 예매 내역을 저장한다 (INSERT).좌석 차감: Event(콘서트) 테이블의 현재 인원수(currentParticipants)를 1 증가시킨다 (UPDATE).논리적으로 완벽해 보이는 이 로직을 들고 부하 테스트를 돌리는 순간, 서버는 처참하게 멈춰 섰다. 로그에는 `Deadlock found when trying to get lock`이라는 에러..
[Lock-6][Optimization] 데이터 정합성을 보장하는 락(Lock)의 종류와 전략
·
Database/MySQL
1. 들어가며: 트랜잭션만으로 해결되지 않는 동시성 문제 이전 포스팅에서는 트랜잭션 격리 수준(Isolation Level)을 통해 데이터 정합성을 보장하는 방법을 살펴보았다. READ COMMITTED, REPEATABLE READ 같은 격리 수준은 트랜잭션 간 읽기 일관성을 보장해 주지만, 멀티 사용자 환경에서 발생하는 모든 동시성 문제를 해결해 주지는 않는다. 대표적인 예가 바로 갱신 분실(Lost Update) 문제다. 예를 들어, 하나의 상품에 대해 동시에 두 개의 주문이 들어온 상황을 생각해 보자.T1: 상품 재고 조회 → 10T2: 상품 재고 조회 → 10T1: 재고 1개 차감 → 9T2: 재고 1개 차감 → 9 각 트랜잭션은 모두 “정상적으로” 동작했다. 따라서 2개가 판매되었으므로 재고..
[Lock-5][Optimization]트랜잭션 실습을 통한 동시성 문제 인식
·
Database/MySQL
1. 들어가며: 한정된 자원과 동시성 문제 데이터베이스 트랜잭션을 다룰 때 가장 빈번하게 발생하는 문제는 한정된 자원에 여러 트랜잭션이 동시에 접근할 때 발생한다. 대표적인 사례로 콘서트 티켓팅, 선착순 쿠폰 발급, 한정판 상품 판매 등이 있다. 수많은 사용자가 찰나의 순간에 '구매' 버튼을 누를 때, 시스템이 어떻게 반응하고 데이터 정합성이 어떻게 무너지는지 코드를 통해 살펴본다.2. 비즈니스 도메인 설계: 이벤트 참가 신청실습을 위해 공연 행사(Event) 도메인을 가정한다. 하나의 이벤트는 최대 참가 인원 제한이 있으며, 시스템은 현재까지 신청한 인원수를 정확히 추적해야 한다.2.1. 엔티티(Entity) 설계Event 엔티티는 최대 인원(maxParticipants)과 현재 인원(currentPa..
[Lock-4][Optimization] Redo/Undo 로그와 MVCC 원리
·
Database/MySQL
1. 들어가며: 데이터베이스는 변경 사항을 어떻게 기억하는가? 데이터베이스의 핵심 원칙 중 하나는 지속성(Durability)이다. 즉, 한번 커밋된 데이터는 시스템에 어떤 장애가 발생하더라도 반드시 보존되어야 한다. 가장 직관적인 방법은 데이터가 변경될 때마다 즉시 디스크에 저장하는 것이다. 하지만 이 방식은 현실적인 성능 한계를 가진다. 디스크는 메모리에 비해 입출력 속도가 매우 느리고, 특히 랜덤 I/O가 발생하면 처리 시간이 급격히 증가한다. 변경이 발생할 때마다 디스크에 직접 쓰기를 수행한다면 커밋 시간이 길어지고, 동시에 처리할 수 있는 트랜잭션 수 역시 크게 줄어들게 된다. 이 문제를 해결하기 위해 InnoDB는 데이터를 즉시 디스크에 반영하지 않는다. 대신 변경 사항을 먼저 기록해 두고..