UPDATE 한 줄로 끝내는 동시성 문제
·
Spring
선착순 이벤트 시스템을 설계한다고 가정해보자. 요구사항은 아래와 같다.요구사항:매일 제한된 수량의 무료 체험 제공선착순 N명 정확히 선정1명만 1개만 주문 가능동시 요청 처리 필수일별 재고 수량 기록 필요단일 데이터베이스 시스템, 여러 개의 서버 컨테이너가장 중요한 것은 동시성 제어이다.100개의 재고가 있을 때 동시에 1,000명이 요청하면 어떻게 정확히 100명에게만 제공할 수 있을까? 이때 일반적으로 제시되는 해결책들은 아래와 같다.비관적 락(SELECT FOR UPDATE)낙관적 락(JPA @Version)데이터베이스 네임드 락Redis 분산 락하지만 단일 데이터베이스 환경에서 분산 락은 오버엔지니어링일 수 있고, 낙관적 락은 재시도 로직이 복잡하며, 비관적 락은 대기 시간이 길어질 수 있다.이 ..
실무에서 @Transactional을 제거했더니 성능이 2배 향상된 이유
·
Spring
Spring에서 @Transactional(readOnly = true)는 DirtyChecking 모드를 Manual 모드로 바꿔줘 성능 최적화를 위해 사용된다고 알려져 있지만, 오히려 불필요한 JDBC 호출로 인해 성능이 저하될 수 있다. 이 글은 Elastic APM을 통해 확인한 실제 호출 로그를 바탕으로 readOnly 트랜잭션이 성능에 어떤 영향을 주는지 분석하고, 실무적으로 더 나은 대안을 제시한다. 아는 사람만 아는 @Transactional의 비밀다음 API는 @Transactional(readOnly = true)로 선언된 Service 메소드를 호출한다. Elastic APM을 통해 추적한 결과, 해당 API는 단 2개의 SELECT 쿼리만 실행함에도 불구하고, 여러 번 JDBC 호출..
[Test] Testcontainers를 사용한 DB 테스트
·
Test
1. TestContainers란?예전에 프로젝트를 할 때 멱등성 있는 테스트를 구성하기 위해 테스트 DB를 따로 띄워 테스트를 실행했던 적이 있습니다. 그 때는 Testcontainers의 존재를 몰랐기에 Docker Compose로 테스트 DB를 띄워 테스트를 실행해줬습니다. 테스트 DB 컨테이너를 계속 띄워 놓기엔 때문에 컴퓨터 리소스 낭비도 심했기 때문에 통합 테스트를 실행해야할 때마다 테스트 DB 컨테이너를 띄워주고 테스트가 종료되면 컨테이너를 내리는 식으로 진행되었는데 정말 귀찮은 작업이었습니다. 이런 작업을 자동화해주는 Testcontainers입니다. 똑같이 Docker 환경을 사용하며 테스트가 실행될 때 실제 DB와 같이 돌아가는 DB 컨테이너를 띄워주고, 테스트가 종료되면 자동으로 컨테..
데이터베이스 인덱스
·
CS/데이터베이스
인덱스를 사용해야하는 근본적인 이유인덱스를 사용하는 이유는 무엇일까? 효율적으로 조회하기 위해서 일 것이다. 그럼 왜 풀텍스트 스캔을 하면 시간이 오래 걸리고, 인덱스를 사용하는 것이 더 효율적일까?데이터베이스의 스토리지 엔진은 컴퓨터와 마찬가지로 하드디스크에 정보를 저장하고 읽어온다. 디스크는 아래 그림과 같이 구성되어 있다. 여기서 섹터는 하드 드라이브의 최소 기억 단위로 트랙의 일부이다. 만약 정보를 읽으라는 명령이 떨어지면 헤드와 암을 열심히 움직여 섹터를 탐색한다. 내용을 읽으려면 암과 헤드가 원하는 track으로 이동해야하고 (빙글빙글 돌고 있는 플래터의) 타이밍이 맞아 헤드와 섹터가 맞닿아야 한다. 이 과정 자체가 굉장히 느리기 때문에 효율적으로 디스크를 조회하려면 최소한의 섹터 범위 안에서..
[Real MySQL] MySQL 역사와 버전 비교 (MySQL 8.0 vs 5.7)
·
MySQL
MySQLMySQL의 역사1979년 스웨덴의 TcX라는 회사의 터미널 인터페이스 라이브러리인 UNIREG로부터 시작되었다. UNIREG는 1994년 웹 시스템의 데이터베이스로 사용하기 시작하면서 MySQL 1.0이 완성되었고, TcX 사내에서만 사용되다가, 1996년에 오픈소스로 공개됐다.2000년 몬티와 데이빗이 MySQL AB라는 회사로 독립함과 동시에 FPL(Free Public License) 라이선스 정책으로 바뀌고 2006년 최종적으로 현재와 같은 두 가지 라이선스 정책(엔터프라이즈 에디션, 커뮤티니 에디션)을 취하게 되었다.이후 썬마이크로시스템즈에 인수되었고, 현재는 오라클에 인수되었지만 특별한 라이선스 정책의 변화는 없었다고 한다.5.x 버전과 8.x 버전MySQL 5.5 ~ 5.7에서는 ..
DISTINCT, GROUP BY 로 중복 제거 하기 [MySQL]
·
MySQL
1. DISTINCT와 GROUP BY이 키워드들은 주로 SELECT와 함께 사용된다.MySQL 에서는 중복된 내용을 단 한 번만 출력하고 싶다면 DISTINCT중복된 내용끼리 묶고 싶다면 GROUP BY 를 사용하면 된다!그렇다면 예시를 통해 이 두 키워드를 알아가보자. 2. 오늘의 예시오늘의 테이블은 물품판매기록서이다. - 테이블 생성CREATE TABLE selling( sequence INT AUTO_INCREMENT PRIMARY KEY, # 판매 순서 product VARCHAR(20), # 품목 price INT, # 가격(원 단위) customer VARCHAR(20), ..