안녕세계
Two-Phase Commit이란?서비스를 개발하다 보면 하나의 사용자 액션이 여러 시스템에 영향을 주는 순간이 옵니다. 예를 들어 사용자가 결제 버튼을 누르면, 주문을 완료하기 위해 결제 승인, 주문 상태 변경, 재고 차감 같은 작업이 연쇄로 일어납니다. 초기에는 한 시스템에서 처리하던 것들도, 서비스가 커지면 역할이 분리되면서 서로 다른 시스템이나 DB에서 처리되기 시작합니다. 이때 요구사항은 단순합니다. 모든 단계가 성공했을 때만 주문을 최종적으로 ‘결제 완료’로 만들고, 중간에 하나라도 실패하면 전체가 완료되지 않게 해야 합니다. Two-Phase Commit(2PC)은 이런 요구를 분산 환경에서 다루기 위한 방식입니다.커머스 서비스에서 자주 발생하는 문제사용자가 쇼핑몰에서 주문을 하면 보통 다음..
반드시 보내고, 한 번만 반영하기 분산 시스템에서 한 요청에서 DB 데이터를 생성(또는 갱신)하고 Kafka로 메시지를 발행해야하는 dual-write 상황에서, 두 시스템 중 하나가 write에 실패하면 데이터 정합성이 깨질 수 있습니다. 또한, Kafka는 최소 한 번(at-least-once) 전달을 기본으로 하므로 동일한 메시지가 여러 번 도착할 수도 있습니다. 본 포스팅에서는 이러한 문제를 Transactional Outbox와 Inbox 패턴으로 메시지를 '반드시 보내고, 한 번만 반영'하는지 설명합니다.Outbox Pattern 📮Outbox의 사전적 의미: (발송 예정 이메일의) 임시 보관함 Outbox Pattern의 핵심은 같은 트랜잭션에서 '도메인 데이터 생성(또는 갱신) + out..
커머스 서비스를 이용하다보면 "주문 후 10분 이내 미결제시 자동 취소됩니다." 와 같은 안내를 볼 수 있습니다. 이처럼 이미 발생한 작업을 후 일정 시간 뒤에 후 처리하는 방법으로 지연 큐(DelayQueue)를 활용할 수 있으며, 대표적인 구현 방식으로 Java 표준 DelayQueue, Amazon SQS DelayQueue, Redis 기반 DelayQueue가 있습니다. 이 글에서는 각 구현 방식에 대해 간략히 살펴보고, 이 중 Redis 기반 DelayQueue의 구체적인 사용 예시를 공유하겠습니다.Java 표준 Delay QueueJava 표준 java.util.concurrent.DelayQueue는 JDK에 내장된 블로킹 지연 큐입니다. DelayQueue는 Delayed 인터페이스를 구..
DriverManagerDriverManager는 JDBC API(Java Database Connectivity API)에서 제공하는 클래스로 데이터베이스와 연결을 직접 생성하고 관리하는 역할을 합니다. (JDBC API에 포함되어있어 별도 설정이 불필요)Connection conn = DriverManager.getConnection( "jdbc:mysql://localhost:3306/mydb", "username", "password");DriverManager는 구체적인 클래스 기반의 API를 통해 데이터베이스와 직접 상호작용합니다. DB 연결 요청 시 매번 새로운 Connection이 생성되고 직접 관리해야합니다. 매 요청마다 새로운 Connection을 하기 때문에 오버헤..
1차 캐시 작동 조건JPA의 1차 캐시는 엔티티를 메모리에 임시로 저장하여 불필요한 DB 쿼리를 줄이고 성능을 향상시키는 중요한 기능입니다. 1차 캐시는 EntityManager가 관리하는 영속성 컨텍스트(persistence context) 내에서 엔티티를 보관하는 저장소로, 주로 트랜잭션 범위 내에서 작동합니다. 즉, 한 트랜잭션 내에서 처음 조회한 엔티티는 두 번째부터 DB에 접근하지 않고 1차 캐시를 통해 데이터를 가져올 수 있게 됩니다. 1차 캐시가 제대로 작동하기 위해서는 몇 가지 조건이 필요합니다. 영속성 컨텍스트 존재1차 캐시는 영속성 컨텍스트 내부에 있으므로, 영속성 컨텍스트가 반드시 존재해야합니다.각 영속성 컨텍스트는 독립적인 1차 캐시를 가지므로, 다른 영속성 컨텍스트에서는 동일 엔티..
지난, 2024년 10월 8일 Amazon ElastiCache에서 Valkey 버전 7.2에 대한 지원이 발표되었습니다. Valkey 캐시 리소스의 Serverless 가격은 Redis OSS 대비 33% 낮은 가격, 자체 설계(노드 기반)의 Cluster 가격은 Redis OSS 대비 20% 낮은 가격으로 이용할 수 있다고 합니다. Valkey에 대해 처음들어 보시는 분들도 있을 것 같은데요. Valkey는 Linux Foundation에서 구축한 오픈 소스이며, Redis OSS 7.2 버전과 완벽하게 호환됩니다. Valkey는 Redis OSS를 대체하는 제품으로 Valkey 전환시 캐시 비용을 절감하고, 최신 ElastiCache 기능의 이점을 누릴 수 있다고 합니다. 캐시 비용 절감을 위해 ..
JPA에서 논리적 삭제(Soft Delete)를 구현할 때 자주 사용하는 방법으로 Hibnerate의 @Where와 @SQLRestriction 어노테이션이 있습니다. 두 어노테이션 모두 특정 컬럼 값을 기준으로 데이터를 자동으로 필터링할 수 있도록 지원합니다. 하지만, 각 어노테이션은 Hibernate 버전에 따라 지원 여부와 동작 방식에 차이가 있으며, 특히 Hibernate 5.x의 @Where는 JOIN 연산 시 전역 조건이 제대로 적용되지 않는 한계가 있습니다. 본 글에서는 실제 테스트 사례를 통해 @Where 어노테이션의 한계를 분석하고, 이를 해결할 수 있는 Hibernate 6.x의 @SQLRestriction 어노테이션을 소개합니다.@Where 어노테이션과 한계@Where는 엔티티 클래스..
Transaction IsolationTransaction Isolation은 데이터베이스에서 여러 트랜잭션이 동시에 실행될 때, 한 트랜잭션이 다른 트랜잭션의 변경 사항을 언제, 어떻게 볼 수 있는지를 결정하는 규칙입니다. 그리고 Transaction Isolation은 여러 트랜잭션이 동시에 실행될 때 서로의 작업에 영향을 주지 않도록 하는 역할을 합니다.Transaction Isolation LevelTransaction Isolation Level은 ANSI SQL 표준으로 READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ, SERIALIZABLE로 4가지가 있으며, MySQL에서 현재 세션에 설정된 Isolation Level을 확인하고 싶은 경우 다음 쿼..