@Transactional
에서 POST
, PUT
, DELETE
와 같이 시스템에 변경을 가하는 외부 API를 호출함
앱과 연결된 데이터베이스는 트랜잭션 롤백이 반영되지만, 외부 API 처리를 롤백해주기 위해서는 별도의 방안이 필요함
POST
, PUT
, DELETE
에 대해서 요청할 때, 특정 키를 기준으로 발생함
API
호출에 대한 응답값을 통해서 사용되는 데이터는 존재하지 않음 (성공적으로 호출 완료 응답만 받는 것이 목적)
API
호출을 코드 마지막 부분에 위치API
호출에 대한 응답값을 받는 것이 목적이므로, API
호출은 항상 코드 마지막 부분에 위치시킬 것이라고 생각할 수 있다.
API
호출이 한 개인 경우는 가능하지만, API
를 여러 개 호출한다면, 이 방법은 적합하지 않다.
특정 메소드는 한 번의 API
만을 마지막에 호출해야 한다는 제약이 생긴다.
@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
패턴에서도 보면 이벤트 발행 방식으로 데이터를 롤백하여 최종 일관성을 통해서 데이터를 맞추는 것을 목적으로 하고 있음
이번 개인적인 상황에서는, AFTER_COMMIT
이벤트 방식을 사용하지 않았는데, SAGA
패턴에서는 트랜잭션 커밋이 발생하면 다른 시스템으로 이벤트를 발행하는 방식을 사용하고 있다.
@TransactionalEventListener
와 SAGA
패턴에서 같은 이벤트 방식으로 데이터를 처리하고 있는데, 이 방식은 데이터가 일관성이 깨지는 순간이 존재할 수 있다는 것도 의미한다.
트랜잭션에서 외부 API를 호출하는 것은 bad practice일까?
데이터베이스의 커넥션 풀은 한정된 리소스이며, MSA
환경에서 시스템을 직접 호출하는 것은 두 시스템의 리소스에 모두 영향을 줄 수 있음
중요한 API 호출이라면, 트랜잭션에 포함될 수도 있다고 생각한다.
이벤트 방식으로 처리하면서, 데이터 일관성이 깨지는 것이 괜찮은가?