개요지난 글에서 Polling 방식을 이용한 Transactional Outbox Pattern에 대해 살펴보았다.해당 방식은 지속적인 DB 조회와 같은 리소스 낭비, 실시간성 저하 등의 단점이 있었다. 이번 글에서는, 이러한 단점을 해결하기 위한 CDC 방식에 대해 살펴보겠다.Debezium이란?Debezium은 데이터베이스 변경 이벤트(Change Data Capture, CDC)를 스트리밍 형태로 캡처하고 전송할 수 있도록 도와주는 오픈 소스 플랫폼이다. 기본적으로 Debezium은 데이터베이스에서 일어나는 INSERT, UPDATE, DELETE와 같은 변경 사항을 실시간 스트림 이벤트로 변환하여 Kafka 등 메시지 브로커를 통해 전송한다.핵심 구성 요소1. Debezium Connector (..
개요현대의 복잡한 비즈니스 환경이나 MSA로 구성된 시스템에서는 동기식 처리 방식의 한계가 자주 드러난다. 이러한 문제를 해결하기 위해 Kafka와 같은 메시지 브로커를 활용한 Event-Driven 아키텍처가 널리 사용되고 있다. 하지만 메시지 브로커를 단순히 도입하는 것만으로는 문제가 끝나지 않는다. 데이터 정합성, 메시지 손실, 중복 처리와 같은 이슈가 여전히 존재한다. 본 글에서는 이러한 문제들이 언제 발생하는지 살펴보고, 이를 해결하기 위한 Transactional Outbox Pattern의 개념과 동작 방식에 대해 소개한다.문제 상황@Transactionalfun createOrder( productId: Long) { // 상품 정보 조회 val product = produ..
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()현재 ..
비관적 락이란?"언제들 충돌 날 수 있어!" 라고 비관적으로 가정하고 미리 락을 걸어 다른 트랜잭션이 못 건드리게 막는 방식이다.작동 방식데이터를 조회할 때부터 DB에 락을 걸어버린다. 읽거나 쓰는 동안 다른 트랜잭션은 이 데이터에 접근이 불가능하다. (대기하거나 실패한다.)장점충돌 방지가 확실데이터를 조회하는 순간부터 락을 걸기 때문에 다른 트랜잭션이 접근할 수 없다. 그러므로 정합성 보장이 중요한 재고 감소, 은행 이제, 예약 시스템 등에 적합하다.복잡한 충돌 처리 로직이 필요 없음낙관적 락처럼 버전 비교 후 실패 시 재시도 등의 코드를 작성할 필요가 없다.단점성능 저하 가능성비관적 락은 락이 걸려 있는 동안 다른 트랜잭션이 대기해야 하므로 동시성이 저하될 수 있다.다만, 데이터의 정합성과 시스템의 ..
낙관적 락이란?"충돌은 잘 안 날거야" 라고 낙관적으로 가정하고 실제로 충돌이 발생하면 그때 처리하는 동시성 제어 방식을 말한다.작동 방식데이터를 읽을 때 버전 번호(@Version)를 함께 읽음데이터를 수정한 뒤, 업데이트 시점에 버전 번호를 비교DB에 있는 버전 번호랑 다르면 실패(다른 누군가가 먼저 수정했음을 의미)충돌 시ObjectOptimisticLockingFailureException 예외가 발생한다.재시도하거나 사용자에게 충돌 메시지를 보여주는 등 예외 처리가 필요하다.장점성능적으로 유리DB에 직접 락을 걸지 않기 때문에 비관적 락보다 성능상 이점이 존재한다.데드락 X마찬가지로 DB에 직접 락을 걸지 않기 때문에 데드락이 발생하지 않는다.분산 환경에 적용 가능JVM 수준이 아닌 DB 수준에..