Tech/SQL

분산 트랜잭션과 XA 트랜잭션에 대해

봄의 개발자 2025. 4. 26. 16:39
728x90
반응형

들어가며

webMethods 개발 중 특정 테이블에 insert 하는 로직을 추가했다가 트랜잭션 관련 에러가 발생해서 난리가 났다...🥲

기존의 로직에서 돌아가던 트랜잭션 안에 이 로직을 추가했어야했는데 거기까지 고려를 하지 못했다. 팀원분들이 알려주시길 XA 트랜잭션을 사용하거나 동일한 트랜잭션 안에 추가해줘야한다고 한다. 그러다가 XA 트랜잭션에 대해서 좀 더 자세하게 알아보고 싶어서 글을 쓰게 되었다. 옛날에 개인 프로젝트 할 때 사가 패턴에 대해서도 잠시 공부를 했었지만 가물가물치....ᐟ

 

분산 트랜잭션이란?

분산 환경에서 데이터 일관성을 유지하기 위한 핵심 기술로, 2개 이상의 네트워크 시스템 간에 이루어지는 트랜잭션을 의미한다.

일반적으로 각 시스템은 트랜잭션 리소스(Transaction Resource)의 역할을 하며, 트랜잭션 매니저(Transaction Manager)는 이러한 리소스에 관련된 모든 동작에 대한 트랜잭션의 생성 및 관리를 담당한다.

 

일반적인 트랜잭션과 동일하게 ACID(원자성, 일관성, 고립성, 지속성) 속성을 반드시 갖춰야 한다.

더보기

1. 원자성(Atomicity): 분리할 수 없는 하나의 단위로 작업은 모두 완료되거나 모두 취소되어야 한다.

2. 일관성(Consistency): 사용되는 모든 데이터는 일관된 상태를 유지해야 한다.

3. 격리성(Isolation): 접근하고 있는 데이터는 다른 트랜잭션으로부터 격리되어야 한다.

4. 지속성(Durability): 트랜잭션이 정상 종료되면 그 결과는 시스템에서 영구적으로 적용되어야 한다.

분산 트랜잭션은 전역 트랜잭션, 글로벌 트랜잭션이라고도 불리며, 여러 리소스 사이에서 처리하는 작업이기 때문에 분산 트랜잭션이라는 이름이 붙었다.

 

XA 트랜잭션

: 표준화된 분산 트랜잭션 구현

XA(eXtended Architecture)는 2PC(2 phase commit)을 통한 분산 트랜잭션 처리를 위해 X-Open에서 명시한 표준이다. 예를 들어 Oracle DB와 IBM DB2 DB 간에 2단계 검증을 통gks 2PC를 보장하여 트랜잭션을 일관되게 처리할 수 있다.

 

XA 구성 요소

1. Transaction Manager(TM): 각 RM(Resource MAnager)별로 XID(트랜잭션 ID)를 생성하여 트랜잭션 진행을 관리하고 전체 RM들의 트랜잭션을 커밋하거나 롤백하는 기능을 수행한다.

2. Resource Manager(RM): 리소스 관리용으로, 흔히 DBMS를 지칭한다.

3. Transaction Processing Monitor(TPM): 통신 프로그램 및 프로세스 관리, 트랜잭션 관리 등 복잡한 부분을 쉽게 처리해주는 미들웨어의 한 종류로 오라클의 Tuxedo나 티맥스의 Tmax와 같은 제품이 있다.

 

2단계 커밋(Two-Phase Commit) 프로토콜

분산 트랜잭션의 가장 일반적인 알고리즘

 

1️⃣단계: Prepare 단계

  • 코디네이터(TM)가 모든 참여자(RM)에게 커밋 준비 요청을 보낸다.
  • 참여자들은 트랜잭션을 커밋할 수 있는지 확인하고, 가능하면 YES! 응답한다.
  • 이 단계에서 각 참여자는 트랜잭션 데이터를 디스크에 쓰고 제약 위반 등을 검증한다.

2️⃣단계: Commit/Rollback 단계

  • 모든 참여자가 YES 로 응답하면, 코디네이터는 커밋 결정을 내린다.
  • 하나라도 NO를 응답하거나 타임아웃이 발생하면 코디네이터는 롤백 결정을 내린다.
  • 코디네이터의 결정(커밋 or 롤백)은 트랜잭션 로그에 기록되고, 모든 참여자에게 전달된다.

 

1단계 커밋(One-Phase Commit)과 최적화

전역 트랜잭션에서 모든 경우 2PC가 필요한 건 아니다. 트랜잭션에 참여한 리소스들이 서로 같은 리소스라고 확인되었을 경우 prepare단계가 필요없다. 이러한 방식을 1PC라고 부른다.

이 경우 prepare 단계를 생략할 수 있으므로 트랜잭션 처리 성능 향상에 도움이 된다. 

주의할 점은 1PC도 전역 트랜잭션이라는 점! 전역 트랜잭션에 참여한 작업들이 모두 같은 리소스에서 처리되어 prepare 작업을 생략하는 것이지, 로컬 트랜잭션으로 전환되는 것은 하니다.

 

 

Global Transaction VS Local Transaction 

기준 Local Transaction Global Transaction
관리 범위 단일 DB  다중 시스템/리소스
ACID 보장 리소스 내부만 전체 시스템 범위
성능 영향  최소 (1000 TPS 이상) 약 30~40% 감소 (650 TPS 수준)
구현 복잡도 낮음 높음
대표 구현 기술 JDBC Connection XA/JTA
관리 주체 개발자 코드 트랜잭션 매니저
동시 연결 허용 1개 연결만 허용 무제한 허용

 

마치며

결국 로컬 트랜잭션 환경에서 다른 DB 작업 추가 시 발생하는 연결 오류는 트랜잭션 관리 범위의 한계에서 비롯된 것이다. 로컬 트랜잭션 연결은 동일 데이터베이스 내에서만 작동하도록 설계되었기에 다른 데이터베이스 연결 시 자원 관리 충돌이 발생할 수밖에 없었던 것이다.

결국 커넥션 라이프 사이클 문제까지 발생하게 되었다.

 

문제 원인

추가 작업1 -> startTransaction() -> 메인 작업 -> commitTransaction() -> 추가 작업2

추가 작업1, 2는 각각 로컬 트랜잭션으로 돌아가고 있고 메인 작업 또한 별도의 로컬 트랜잭션으로 돌아가고 있는데, 결국 서로 트랜잭션 컨텍스트를 공유하지 못해 커넥션 종료 불가 에러가 발생했던 것으로 추측된다.

  • 트랜잭션 경계 중첩: 추가 작업1/2와 메인 작업의 트랜잭션 시작/종료 시점이 완전히 분리되지 않음
  • 로컬 트랜잭션 한계: 단일 DB 연결만 허용하는 특성으로 인해 다중 작업 시 제어 불가
    • 단일 트랜잭션 컨텍스트에서 2개 이상의 로컬 커넥션 사용 불가
    • startTransaction()  (Adapter 1 + Adapter 2)  commitTransaction() 충돌!

해결 방법

1. XA 트랜잭션으로 유형 변경

단일 db여도 다른 커넥션 풀 사용시 필수로 XA 트랜잭션을 사용해야한다.

2. 명시적 트랜잭션 중첩 관리

[메인 트랜잭션 시작]
-> [서브 트랜잭션1 시작] -> [Adapter1 실행] -> [서브 트랜잭션1 커밋]
-> [서브 트랜잭션2 시작] -> [Adapter2 실행] -> [서브 트랜잭션2 커밋]
-> [메인 트랜잭션 커밋]

 

 

참고)

728x90
반응형