본문 바로가기

연구 과제 (끝나면 해당 카테고리로 이동)

분산 트랜잭션 (2)

728x90
반응형

사이드카 패턴에 대해서 알아보고 이것저것 해보다가 문뜩 분산 트랜잭션에 대해서 궁금증이 생겼다.

일단 트랜잭션이란 무엇인지 잠깐 정리하자면,

 

트랜잭션은 데이터베이스에서 하나의 논리적 작업 단위를 의미하며, 여러 개의 데이터베이스 연산을 하나의 작업으로 묶어 처리하는것을 의미한다. 트랜잭션의 주요 특징은 ACID 속성으로 요약된다.

BEGIN TRANSACTION: 트랜잭션의 시작을 알린다.
COMMIT: 트랜잭션을 성공적으로 완료하고, 모든 변경 사항을 데이터베이스에 영구적으로 반영을 수행 한다.
ROLLBACK: 트랜잭션을 취소하고, 모든 변경 사항을 원래 상태로 되돌리는 작업을 수행한다.
SAVEPOINT: 트랜잭션 내에서 특정 지점을 저장하여, 필요 시 해당 지점으로 롤백할 수 있게 한다.

 

1. 분산 환경에서의 트랜잭션

분산 트랜잭션 이란?

분산 트랜잭션은 여러 데이터베이스나 시스템에 걸쳐 수행되는 트랜잭션을 의미한다. 이는 단일 트랜잭션이 여러 노드나 데이터베이스에 걸쳐 일관성 있게 수행되도록 보장한다.

분산 트랜잭션은 주로 분산 데이터베이스 시스템에서 사용되며, ACID 속성을 유지하기 위해 특별한 프로토콜과 메커니즘을 사용하여 트랜잭션을 보장한다.

 

위의 내용만 봐도 머리가 좀 아플거 같다.

분산 트랜잭션에 대한 고민을 하지 않았던 이유가 분산 트랜잭션으로 구현을 하거나 운영을 해야하는 상황에 노출이 됐던적이 없었었다. 그래서 트랜잭션이 이렇게 어려운 개념? 이란걸 슬슬 느끼는 중이다.

 

분산트랜잭션과 관련된 환경에 노출된 적이 없다고해서 손놓고 있을수는 없으니, 일단 분산 트랜잭션 환경을 직접 구현을 해보기로 했다.

 

첫번째로 고민했던게 트랜잭션을 어떻게 발생 시킬까 였다. 간단한 코드를 만들고 트랙잭션을 발생 시켜보기로 했다.

payments 서비스나 reservation 서비스를 구현하여 테스트를 진행 했다. (말만 결제와 예약이지... 그냥 POST, GET 하는 코드다.)

 

아 근데 나중에 분산 트랜잭션도 테스트를 해봐야 하니, 이왕 하는거 SAGA Pattern을 적용시켜서 해보기로 했고,

관련된 내용은 아래와 같다.

 

아래의 내용은 간단하게 트랜잭션을 발생시키는 내용이다. 특이한건 동일한 PK로 다시한번 POST를 하면 상태값이 COMPLETED에서 CANCELLED로 변한다.

아래의 서비스 내용은 Reservation 서비스 내용이고, 위의 내용보다는 조금 확장 시켜봤다.

Reservation 서비스는 총 6개의 스텝으로 나누고 각 스텝별로 Status값을 DB에 저장하도록 구현 했다. 보통 예약을 할때 한 3~4개의 스탭을 거쳐서 최종 결제가 되거나 예약이 되니 스텝을 나눠서 만들어 봤다.

간단하게 보면 DB 테이블 데이터는 아래와 같다.

간단한 테스트는 아래와 같다.

 

각 스텝 별로 별도의 로직을 구현하면 총 6개의 스텝별로 독립적인 프로세싱 로직을 구현할 수 있다.

2. UI가 존재하는 결제 화면 만들기

이왕 하기로한거 분산 트랜잭션 까지 해봐야 하니, 조금 더 확장 시켜 보기로 했다.

UI를 간단하게 만들어 봤다.

파라미터 값들은 어디에서 받아올 수가 없으니, 입력 칸을 만들었다.

여기서 중점적으로 생각한건 결재 진행과정에서 반려가 됐을때, 롤백 로직을 어떻게 구현을 할까 였다.

반려 라는건 결제로 치면 결재를 중간에 취소한 상황이니, 해당 내용을 어떻게 처리를 해야할지 고민을 아주 짧게 했다.

결제는 만약에 결제자가 반려를 한다면, 상태값에 Rollback이라고 남겨 주는걸로 간단하게 정했다.

결과 적으로 보상 트랜잭션을 수행한다는 의미 였는데, 롤백의 의미에 대해서 다시한번 생각해 본 계기가 된거 같다.

내가 기존에 생각했던 롤백은 그냥 단순히 되돌리다 라는 의미로 생각 했었었다. 실패 했으니 이전의 상태로 되돌려 놓는것 ? 정도로 생각을 했었다.

새롭게 롤백을 정의하자면 아래와 같다.

롤백(rollback)은 데이터베이스 트랜잭션에서 이전에 성공적으로 수행된 작업들을 원래 상태로 되돌리는 것을 의미한다. 이는 데이터의 일관성을 유지하고, 실패한 작업으로 인해 데이터베이스가 불안정한 상태가 되는 것을 방지하는것을 의미한다.

내가 만들고 테스트한 프로젝트에서의 롤백은 아래와 같다.

ApprovalOrchestrator라는 클래스의 rejectStep 메서드에서 compensateApproval 메서드를 호출하여 롤백을 수행하는 경우, 이전에 성공한 프로세스의 모든 스텝을 원래 상태로 되돌리는 것을 의미한다.

구체적으로, 각 스텝의 모든 상태를 "ROLLED_BACK"로 변경하고, 최종적으로 승인 테이블의 상태를 "CANCELLED"로 업데이트한다. 위와 관련된 내용을 좀 더 자세히 설명하면 아래의 동영상과 같다.

executeApprovalSaga > processApproval > ApprovalStep > execute 전부 실행, 중간에 에러나면 보상 트랜잭션 수행

나머지는 밤에 쓰자...

728x90
반응형