전체 글

개요회사에서 기존 QueryDSL 코드를 Kotlin JDSL로 전환하는 작업을 진행 중이었다.전환 과정에서 페이징 처리가 필요한 API에 findPage를 사용했는데, 자동 생성되는 count 쿼리가 예상과 다르게 동작하는 문제를 만났다. 해결책을 찾다가 공식 문서에서 findPage(pageable, query, countQuery) 형태로 count 쿼리를 직접 지정할 수 있다는 예제를 발견했다. 하지만 실제 KotlinJdslJpqlExecutor 인터페이스에는 해당 오버로드가 존재하지 않았다. 문서에는 있지만 실제 API에는 없는 기능. 이 불일치를 발견한 것이 첫 오픈소스 기여의 시작이었다.📄 공식문서: https://kotlin-jdsl.gitbook.io/docs📝 Issue: line..
개요이번 글에서는 MySQL에서 부하를 분산하고 가용성을 높이기 위해 자주 활용되는 Replication에 대해 다뤄보려 한다. 우선, 기본적인 1 Master 1 Replica 구조를 직접 구현하고, Spring Boot에서 어떻게 연동하는지에 대해 작성한다.MySQL Replication이란?MySQL Replication은 하나의 MySQL 서버(Master)에서 발생한 데이터를 다른 MySQL 서버(Replica)로 비동기적으로 전파하는 기술이다. 이 기능을 통해 여러 개의 데이터베이스 서버 간에 데이터를 자동으로 동기화할 수 있으며, 읽기 부하 분산, 고가용성, 백업 무중단화, 장애 복구 등의 다양한 목적에 활용된다.작동 방식1단계 : Master에서 Binary Log 생성클라이언트가 Mas..
개요MySQL 5.7.23부터 새로운 비밀번호 인증 플러그인인 caching_sha2_password가 도입되었다. 초기에는 선택적으로 사용할 수 있었고, 기본 인증 플러그인은 여전히 mysql_native_password였다. 그러나 MySQL 8.x부터는 caching_sha2_password가 기본 인증 방식으로 채택되면서 클라이언트 호환성과 보안 정책에 큰 변화가 생기기 시작했다.그리고 MySQL 9.x부터는 mysql_native_password 플러그인의 공식 지원이 중단되었으며, 이에 따라 caching_sha2_password 또는 sha256_password 플러그인을 사용해야 한다. 이 변화는 단순한 인증 방식 변경을 넘어 SSL 연결을 필수 요건으로 만들었다. 이번 글에서는 MySQL..
개요지난 글에서 Polling 방식을 이용한 Transactional Outbox Pattern에 대해 살펴보았다.해당 방식은 지속적인 DB 조회와 같은 리소스 낭비, 실시간성 저하 등의 단점이 있었다. 이번 글에서는, 이러한 단점을 해결하기 위한 CDC 방식에 대해 살펴보겠다.Debezium이란?Debezium은 데이터베이스 변경 이벤트(Change Data Capture, CDC)를 스트리밍 형태로 캡처하고 전송할 수 있도록 도와주는 오픈 소스 플랫폼이다. 기본적으로 Debezium은 데이터베이스에서 일어나는 INSERT, UPDATE, DELETE와 같은 변경 사항을 실시간 스트림 이벤트로 변환하여 Kafka 등 메시지 브로커를 통해 전송한다.핵심 구성 요소1. Debezium Connector (..
Propagation.REQUIRES_NEW란?REQUIRES_NEW는 Spring의 트랜잭션 전파 속성 중 하나로, 독립적인 새로운 트랜잭션을 시작할 때 사용한다.현재 트랜잭션이 존재하든 말든, 무조건 새로운 트랜잭션을 시작한다.기존 트랜잭션이 존재할 경우 잠시 중단되고, 새로운 트랜잭션이 완전히 별도로 실행된다.사용 시기로깅, 알림, 감사 로그 등 독립적 저장이 필요한 작업부모 트랜잭션의 롤백 여부와 상관 없이 저장되어야 하는 작업을 할 때 사용한다.트랜잭션 범위 최소화락 범위나 예외 영향을 줄이고 싶을 때 사용한다.경우에 따른 롤백하위 메소드에서 예외 발생아래 예제를 보면 상위 메소드의 결과까지 롤백이 된 것을 볼 수 있다.분명 REQUIRES_NEW를 사용하면 독립적인 트랜잭션이라 했는데 왜 이런..
MySQL Named 락이란?MySQL에서 제공하는 이름 기반의 사용자 락이다.동시성 제어를 위해 DB 안에서 간단히 분산락처럼 사용할 수 있는 기능이다.주요 함수GET_LOCK(name, timeout)입력 받은 name으로 timeout 초 동안 잠금 획득을 시도한다.timeout에 음수를 입력하면 잠금을 획득할 때까지 무한대로 대기한다.한 세션에서 잠금을 유지하고 있는 동안 다른 세션에서 동일한 이름의 잠금 획득이 불가능하다.GET_LOCK()을 이용하여 획득한 잠금은 트랜잭션이 커밋/롤백 되어도 풀리지 않는다.즉, 락을 잡은 커넥션에서 직접 해제하거나 DB 커넥션이 종료되어야 락이 풀린다.RELEASE_LOCK(name)입력 받은 name의 잠금을 해제한다.RELEASE_ALL_LOCKS()현재 ..
포테이토웅
포테이토웅의 개발 블로그