Seata 2.6.0 AT 분산 트랜잭션: 배포와 연동부터 장애 경계까지
이 글은 Seata 2.6.0, Spring Boot 3, 이에 대응하는 버전의 Spring Cloud Alibaba 및 MySQL 8을 기준으로 작성되었습니다. Seata, Spring Boot, Spring Cloud Alibaba, Nacos 및 클라이언트 의존성은 공식 호환성 매트릭스에 따라 조합해야 하며, 한 구성 요소만 업그레이드해서는 안 됩니다.
먼저 결론부터
Seata AT은 하나의 비즈니스 작업에서 여러 관계형 데이터베이스를 수정해야 하고, 참여자가 잠시 전역 락 경합을 감수할 수 있으며, 최종 일관성보다 더 강한 롤백 의미가 필요한 환경에 적합합니다.
AT은 ‘모든 분산 작업을 자동으로 롤백’하는 기능이 아닙니다. 이미 전송된 메시지, 호출된 서드파티 API, 캐시에 기록된 데이터를 자동으로 되돌릴 수 없으며, 멱등성, 재시도, 보상 트랜잭션, 신뢰성 있는 메시지를 대신할 수도 없습니다.
핵심 흐름은 다음과 같습니다.
1. 구성 요소와 용어
- TC(Transaction Coordinator): 전역 트랜잭션, 브랜치 트랜잭션 및 전역 락을 관리합니다.
- TM(Transaction Manager): 전역 트랜잭션의 시작, 커밋 및 롤백을 담당합니다.
- RM(Resource Manager): 브랜치 등록, 결과 보고 및 로컬 롤백 실행을 담당합니다.
Seata 클라이언트는 일반적으로 TM과 RM을 모두 포함합니다.
订单服务(TM + RM)
-> 库存服务(RM)
-> 账户服务(RM)
|
v
Seata TC
@GlobalTransactional은 보통 전역 트랜잭션의 진입점에 둡니다. 참여 서비스는 새 전역 트랜잭션을 시작할 필요가 없지만, 전역 트랜잭션에 참여하는 데이터베이스를 사용하는 모든 서비스는 Seata 데이터소스 프록시에 올바르게 연결되어야 합니다.
2. AT의 실제 실행 과정
UPDATE 한 건을 예로 들면, RM은 로컬 트랜잭션에서 대략 다음 작업을 수행합니다.
- SQL을 해석해 테이블, 기본 키 및 수정 범위를 파악합니다.
- 수정 전 before image를 조회합니다.
- 업무 SQL을 실행합니다.
- 수정 후 after image를 조회합니다.
- undo_log를 기록합니다.
- 브랜치 트랜잭션을 등록한 뒤 로컬 트랜잭션을 커밋합니다.
전역 커밋 시 TC는 각 브랜치에 커밋을 지시합니다. 1단계에서는 이미 로컬 커밋이 끝났으므로, 2단계는 주로 undo_log를 비동기적으로 정리하는 작업입니다.
전역 롤백 시 RM은 undo_log를 읽고 현재 데이터가 after image와 일치하는지 검증한 다음, before image를 바탕으로 역방향 작업을 생성해 로컬 트랜잭션에서 롤백을 실행합니다.
따라서 AT은 데이터베이스 스냅샷도, 고정된 역방향 SQL도 아닙니다. SQL 해석, 전후 이미지, undo_log 및 전역 락에 의존합니다.
3. Seata 2.6.0 배포 원칙
현재 기준 버전은 Seata 2.6.0입니다. latest를 사용하지 말고, Seata 1.x의 설정 파일, 필드 및 데이터베이스 스크립트를 2.x에 그대로 복사해 사용하지 마세요.
학습 환경에서는 TC가 file 등록과 file 저장소를 사용하도록 구성한 뒤 비즈니스 흐름부터 검증할 수 있습니다. 운영 환경에서는 일반적으로 Nacos 같은 등록·설정 센터를 사용하고, 데이터베이스 또는 공식에서 지원하는 고가용 저장소를 사용해야 합니다.
TC에서 store.mode=db를 사용할 때는 Seata 2.6.0 릴리스 패키지의 해당 데이터베이스 디렉터리에 있는 MySQL 스크립트를 실행해야 합니다. 스크립트에는 최소한 다음 항목이 포함되어야 합니다.
global_table 全局事务
branch_table 分支事务
lock_table 全局锁
distributed_lock TC 集群协调
vgroup_table 事务组映射
AT에 참여하는 각 업무 데이터베이스에는 동일 버전 클라이언트에 대응하는 undolog 테이블 스크립트도 실행해야 합니다. TC 테이블과 업무 데이터베이스의 undolog는 서로 다른 종류의 테이블입니다.
AT 데이터소스에는 일반적으로 다음 조건이 필요합니다.
- MySQL은 InnoDB를 사용해야 합니다.
- 업무 테이블에는 안정적인 기본 키가 있어야 합니다.
- SQL을 Seata가 해석할 수 있어야 합니다.
- 데이터베이스 계정에 undo_log를 생성하고 쓸 수 있는 권한이 있어야 합니다.
- undo_log, 업무 SQL 및 로컬 트랜잭션은 동일한 데이터베이스 커넥션 범위를 사용해야 합니다.
Docker 이미지, JDK, 클라이언트 의존성 및 데이터베이스 스크립트는 동일한 호환 조합에서 제공되어야 합니다. 운영 환경에서 TC 관리 포트를 공인망에 노출하지 마세요.
4. Spring Boot 클라이언트 연동
의존성 버전은 서로 독립적인 버전 번호를 임의로 입력하지 마세요. Spring Boot, Spring Cloud, Spring Cloud Alibaba 및 Seata의 호환성 매트릭스를 기준으로 BOM 또는 dependency management를 사용해야 합니다.
설정 개념은 다음과 같으며, 실제 속성명은 현재 클라이언트 버전의 설정 메타데이터를 기준으로 합니다.
seata:
enabled: true
tx-service-group: order_tx_group
enable-auto-data-source-proxy: true
data-source-proxy-mode: AT
Nacos를 사용할 때는 등록 센터와 설정 센터 모두 server-addr, namespace, group, username 및 password를 명시적으로 설정해야 합니다. 자격 증명은 환경 변수나 secret을 통해 주입하고 Git에 커밋하지 마세요.
시작 후 다음 항목을 확인해야 합니다.
- Seata 클라이언트가 초기화되었는가
- 데이터소스가 Seata에 의해 프록시되었는가
- RM이 TC에 등록되었는가
- TM이 TC에 등록되었는가
- 트랜잭션 그룹이 사용 가능한 TC 클러스터에 매핑되었는가
여러 데이터소스를 사용하는 환경에서는 자동 설정에만 의존하지 말고, 각 데이터소스의 프록시, Mapper 스캔 및 트랜잭션 매니저를 명시적으로 검증해야 합니다.
5. 비즈니스 예시
전역 진입점:
참여 서비스는 로컬 비즈니스 처리를 담당합니다.
핵심은 애노테이션의 개수가 아니라 경계입니다.
- 전역 진입점에서는 @GlobalTransactional을 사용합니다.
- 참여 데이터베이스의 각 로컬 작업에는 명확한 트랜잭션 경계가 있어야 합니다.
- 원격 호출이 실패하면 식별 가능한 예외를 발생시켜야 합니다.
- 재고 차감과 계좌 차액은 반드시 멱등해야 합니다.
- 재시도로 재고나 금액이 중복 차감되지 않아야 합니다.
HTTP, RPC 또는 메시지 큐를 사용하는 경우 XID가 전파될 수 있는지 반드시 확인해야 합니다. 진입점에 애노테이션만 추가하고 XID를 전파하지 않으면 참여 서비스는 같은 전역 트랜잭션에 참여하지 않습니다.
6. AT의 실패 경계
다음 SQL은 중점적으로 검증해야 합니다.
- 복잡한 JOIN, 서브쿼리 및 일괄 업데이트
- 기본 키가 없는 테이블
- 기본 키 또는 파티션 키를 수정하는 쿼리
- 대량의 데이터 업데이트
- 저장 프로시저, 트리거 및 데이터베이스 특수 문법
- 긴 트랜잭션과 경합이 심한 핫스팟 행
업무 메서드가 성공을 반환하는지만 확인해서는 안 됩니다. 장애 주입 테스트를 통해 롤백 결과, 락 해제 및 undo_log 정리 상태를 확인해야 합니다.
AT은 외부 부수 효과를 다루지 않습니다.
数据库提交 -> 发送 MQ 消息 -> 调用支付接口 -> 写入 Redis
이러한 작업은 비즈니스 요구사항에 따라 Outbox, 로컬 메시지 테이블, 신뢰성 있는 메시지, 멱등 소비, 상태 머신, 보상 트랜잭션, TCC 또는 Saga 중 적합한 방식을 선택해야 합니다.
전역 락 역시 무비용 기능은 아닙니다. 핫스팟 상품, 계정 및 재고에서는 락 경합이 발생해 브랜치 등록이 느려지고, 트랜잭션 대기, 롤백 지연 및 스레드 풀에 작업이 쌓이는 현상이 나타납니다. 트랜잭션 시간을 줄이고, 트랜잭션 안에서 불필요한 원격 호출을 피하며, 자원을 일관된 순서로 업데이트하고, 락 대기 및 롤백 재시도를 모니터링해야 합니다.
7. 장애 테스트 체크리스트
최소한 다음 항목을 테스트해야 합니다.
- 재고 서비스 타임아웃
- 계정 서비스가 비즈니스 실패를 반환하는 경우
- 한 브랜치가 로컬 커밋된 상태에서 다른 브랜치가 실패하는 경우
- TC 재시작
- 데이터베이스 커넥션 풀 고갈
- after image 검증 실패
- 중복 요청 및 클라이언트 재시도
- 네트워크 응답 손실
- 서비스 배포 중 버전 호환성
매번 다음 항목을 확인해야 합니다.
业务表最终状态
global_table
branch_table
lock_table
undo_log
日志中的 XID
운영 로그에서는 요청, 데이터베이스 브랜치, 원격 호출 및 예외 로그에 XID를 일관되게 출력해야 합니다. 다만 비밀번호, token 또는 민감한 비즈니스 데이터는 출력하지 마세요.
8. 운영 체크리스트
- Seata Server, 클라이언트, Spring Boot 및 Spring Cloud Alibaba 버전이 서로 호환되어야 합니다.
- 모든 이미지와 의존성을 고정 버전으로 지정해야 합니다.
- TC는 고가용성 방식으로 배포해야 하며, 운영 장애 복구에 file 저장소를 사용하면 안 됩니다.
- Nacos, 데이터베이스 및 TC는 내부망을 통해 접근해야 합니다.
- 설정과 자격 증명은 secret 또는 외부 설정을 통해 주입해야 합니다.
- 각 업무 데이터베이스에 해당 버전의 undo_log 테이블이 있어야 합니다.
- TC 데이터베이스를 백업하고 정리 정책을 설정해야 합니다.
- 전역 트랜잭션에 타임아웃, 재시도 및 폴백 전략이 있어야 합니다.
- 외부 부수 효과에 대한 멱등 또는 보상方案이 있어야 합니다.
- XID, 트랜잭션 소요 시간, 롤백률, 락 대기, 타임아웃, 재시도 및 undo_log 개수를 모니터링해야 합니다.
9. AT을 사용하지 말아야 할 때
다음 경우에는 일반적으로 다른 방식을 검토해야 합니다.
- 트랜잭션이 메시지, 결제, 파일 및 서드파티 API에 걸쳐 있는 경우
- 하나의 전역 트랜잭션이 오래 지속되는 경우
- 핫스팟 행의 경합이 심한 경우
- SQL을 안정적으로 해석할 수 없거나 기본 키가 없는 경우
- 최종 일관성이 더 중요한 경우
- 팀에 TC, 데이터베이스 스크립트, 모니터링 및 장애 훈련을 유지할 역량이 없는 경우
Seata AT은 분산 시스템을 단일 서버의 트랜잭션처럼 만들어 주지는 않습니다. 적합한 데이터베이스 경계 안에서 자동적인 조율과 보상 메커니즘을 제공할 뿐입니다. 이를 올바르게 사용하려면 경계를 명확히 하고, 버전을 고정하며, 트랜잭션 길이를 통제하고, 실패 경로에 대해 실제로 테스트해야 합니다.
참고 자료
- Seata 공식 저장소 및 v2.6.0 릴리스
- Seata AT Mode 공식 문서
- Seata 2.6.0에 대응하는 동일 버전 데이터베이스 스크립트
- Spring Boot 및 Spring Cloud Alibaba 공식 호환성 매트릭스
- Nacos 공식 배포 및 인증 문서
최종 점검 일시: 2026-07.