External API in @Transactional

0️⃣1️⃣·2024년 3월 9일
0

개발

목록 보기
7/7

Situation

  • @Transactional에서 POST, PUT, DELETE와 같이 시스템에 변경을 가하는 외부 API를 호출함

  • 앱과 연결된 데이터베이스는 트랜잭션 롤백이 반영되지만, 외부 API 처리를 롤백해주기 위해서는 별도의 방안이 필요함

  • POST, PUT, DELETE에 대해서 요청할 때, 특정 키를 기준으로 발생함

  • API 호출에 대한 응답값을 통해서 사용되는 데이터는 존재하지 않음 (성공적으로 호출 완료 응답만 받는 것이 목적)


Solution

API 호출을 코드 마지막 부분에 위치

  • API 호출에 대한 응답값을 받는 것이 목적이므로, API 호출은 항상 코드 마지막 부분에 위치시킬 것이라고 생각할 수 있다.

  • API 호출이 한 개인 경우는 가능하지만, API를 여러 개 호출한다면, 이 방법은 적합하지 않다.

  • 특정 메소드는 한 번의 API만을 마지막에 호출해야 한다는 제약이 생긴다.

@TransactionalEventListener 사용

@TransactionalEventListener(phase = TransactionPhase.AFTER_ROLLBACK)
public void rollback(CustomEvent customEvent) {
	if (customEvent.failProcess1()) {
    	// rollback Api server1 Process
    }
    
    if (customEvent.failProcess2()) {
    	// rollback Api server2 Process
    }
    
    ...
}
  • 발행된 이벤트를 통해서, 어떤 API 호출에 대해서 롤백해야 하는지 명시적으로 파악할 수 있음

  • SAGA 패턴에서도 보면 이벤트 발행 방식으로 데이터를 롤백하여 최종 일관성을 통해서 데이터를 맞추는 것을 목적으로 하고 있음


Opinion of Event

이번 개인적인 상황에서는, AFTER_COMMIT 이벤트 방식을 사용하지 않았는데, SAGA패턴에서는 트랜잭션 커밋이 발생하면 다른 시스템으로 이벤트를 발행하는 방식을 사용하고 있다.

@TransactionalEventListenerSAGA 패턴에서 같은 이벤트 방식으로 데이터를 처리하고 있는데, 이 방식은 데이터가 일관성이 깨지는 순간이 존재할 수 있다는 것도 의미한다.

트랜잭션에서 외부 API를 호출하는 것은 bad practice일까?

  • 데이터베이스의 커넥션 풀은 한정된 리소스이며, MSA 환경에서 시스템을 직접 호출하는 것은 두 시스템의 리소스에 모두 영향을 줄 수 있음

  • 중요한 API 호출이라면, 트랜잭션에 포함될 수도 있다고 생각한다.

이벤트 방식으로 처리하면서, 데이터 일관성이 깨지는 것이 괜찮은가?

  • 도메인에 따라서, 데이터 일관성을 어디까지 맞출 것인가 에 대해서 논의를 통해서 결정하는 것이 맞아보인다.

0개의 댓글