📗

Trigger & Procedure / Saga & Event-Driven Architecture / 2PC

트리거

트리거를 건다
어떤 트랜잭션 일어날 때 반응 → 다른 명령 실행하게 하는 것
테이블에 대한 이벤트(INSERT, UPDATE, DELETE)에 반응 → 자동으로 실행
DDL, DML, 일부 DB 작업
⇒ 데이터 무결성, 특정 작업 자동화
ex. 결제 삽입, 업데이트 → 실시간 결제상태/이력 테이블 업데이트

프로시저

프로시저를 실행한다
일련의 쿼리 작업 → 하나의 함수처럼 실행하기 위한 쿼리 집합
미리 SQL문 작성, 필요할 때마다 호출
읽기 성능 최적화, data 조회
ex. 결제 프로시저 정의(결제 승인 → 기록 삽입 → 잔고 갱신 → 알림 전송)
⇒ 트랜잭션 실패 → 롤백 ⇒ 데이터무결성
트리거
프로시저
이벤트 발생할 때마다
필요할 때마다
내부에서 프로시저 정의 O
내부에서 트리거 정의 X 트리거: 이벤트 발생 시 자동 호출
매개변수 값이나 코드 반환 X
매개변수 값이나 코드 반환 O (리턴하는 값 없어도 됨. 수행하는 절차가 목적)

MSA

확장성, 독립성, 유지보수성

DB에 의존적
DB도 함께 확장해야 함
다른 서비스와 공유되는 DB 부하 커짐 → 장애 발생 가능
DB 로직 변경 → 여러 서비스 영향 ⇒ 쉽게 확장 X

트랜잭션

ACID(원자성, 일관성, 격리성, 내구성)

원자성: 모두 발생 or 발생 X 불가역적이고 돌이킬 수 없는 작업 세트
일관성: 유효한 상태의 데이터만 다른 유효한 상태로 가져온다는 것
격리성: (동시 트랜잭션 == 순차적으로 실행된 트랜잭션이 생성한 것과 동일한 데이터 상태 생성) 보장
내구성: 시스템 오류 or 정전 시에도 커밋된 트랜잭션이 커밋된 상태로 유지
⇒ 데이터베이스 의존도 낮추면서 트랜잭션 무결성 보장 필요 → 분산 트랜잭션 관리 전략 채택

1. 사가패턴(Saga Pattern)

복잡한 트랜잭션 → 서비스 단위로 분산시키기 위해 적합한 패턴
트랜잭션 중 오류 발생 → 보상 트랜잭션 ~> 이전 단계 취소 ⇒ 데이터 일관성 보장

1) 코레오그래피 기반 사가(Choreography-based Saga)

각 서비스가 이벤트 발행하고 구독하여 상호작용
(+) 중앙 관리 X 분한된 환경에서 빠르게 대응 O
각 서비스가 서로의 상태를 알지 못하는 상황 발생할 수 있음
전체 트랜잭션 상태나 흐름 추적 어려움
워크플로우의 확장과 변경 어려움
새로운 단계 추가 or 기존 워크플로우 변경 → 모든 관련 서비스 수정
(-) 복잡한 워크플로우 O → 서비스 간 이벤트 흐름 엉킬 위험 있음
다수의 서비스 순차적으로 관여 → 이벤트 여러 단계로 연쇄적으로 전달 ⇒ 이벤트 흐름 복잡
예외 처리 및 데이터 일관성 유지 어려움

2) 오케스트레이션 기반 사가(Orchestration-based Saga)

중앙에서 오케스트레이터가 전체 워크플로우 관리
오케스트레이터) 각 서비스에 작업 요청, 결과에 따라 다음 단계 결정
/ 각 단계 결과 평가, 조건에 따라 다음 단계로 분기할 수 있음, 다양한 예외 상황에 유연하게 대응할 수 있음
(+) 중앙 관리로 복잡한 트랜잭션 쉽게 추적할 수 있음
실패 시 어떤 단계로 돌아가야 할지 쉽게 결정, 보상 트랜잭션 명확히 수행할 수 있음
서비스 간 데이터 일관성 유지 쉬움
(-) 중앙 서비스 과부하 or 장애 발생 → 전체 워크플로우에 영향 줄 수 있음

2. 이벤트 기반 아키텍처와 메시지 브로커 (Event-Driven Architecture & Message Broker)

각 서비스가 독립적으로 실행되고 이벤트 발행 → 서로 필요한 데이터 주고받는 방식
Kafka, RabbitMQ 등의 메시지 브로커 사용 → 비동기적으로 이벤트 전달
이벤트 메시지 ~> 데이터 일관성 유지 + 트랜잭션 관리

3. CQRS와 이벤트 소싱(CQRS and Event Sourcing)

읽기와 쓰기 모델 분리 → 데이터베이스 성능 최적화
이벤트 소싱
모든 상태 변경 사항 기록 → 데이터 일관성 관리
전체 이벤트 재생 → 시스템의 최종 상태 구성
성능상 부담
⇒ 읽기 성능 최적화 or 데이터 조회할 때 활용 → 복잡한 트랜잭션 워크플로우와 상태 일관성 유지에 적합 X

4. 비동기 통신 및 API

각 서비스가 독립적으로 다른 서비스의 API 호출 or 비동기로 메시지 전달해 상호작용하는 방식
서비스 간 결합도 낮춤
But, 트랜잭션의 전체 흐름을 중앙에서 관리하고 상태 유지 X
각 서비스가 독립적으로 작동 → 이벤트 순서 보장 X

2PC(Two-Phase commit)

원자성을 보장하기 위한 분산 트랜잭션 관리 프로토콜
여러 노드 상에서의 원자적 트랜잭션 커밋을 이루기 위한 알고리즘(프로토콜)
분산된 환경에서 여러 노드(여러 데이터베이스 or 서비스)가 하나의 트랜잭션을 성공적으로 커밋할 때까지 2 단계에 걸쳐 트랜잭션을 진행하는 프로토콜
일반적인 싱글 노드 트랜잭션에 존재하지 않는 새로운 컴포넌트인 코디네이터(트랜잭션 매니저) 사용
코디네이터: 트랜잭션을 요청하는 같은 애플리케이션 프로세스 내 라이브러리에 구현되어 있으나, 분리된 서비스나 프로세스일 수 있음
애플리케이션) 여러 데이터베이스 노드들에 읽고 쓰면서 시작
준비 단계 (Prepare Phase)
애플리케이션이 커밋할 준비 → 코디네이터) phase 1 시작, 각 노드에 prepare 요청 → 커밋할 수 있는지 질의, 코디네이터) 이후 각 노드(참여자, participant)의 응답 추적
커밋 단계 (Commit Phase)
모든 참여자 yes → 코디네티어) phase 2로 넘어가 commit 요청 → 커밋 수행되도록 함
어느 하나라도 no → 코디네이터) phase 2로 넘어가 모든 노드들에 abort 요청

그래서 우리 프로젝트에선?

강한 일관성 필요한 시스템 ⇒ 2PC