내가 생각하는 것보다 더 많은 것을 타협하는 많은 솔루션이 있습니다. 물론 다른 은행간에 돈을 옮기는 것과 같이 유스 케이스가 복잡한 경우 더 유쾌한 대안이 불가능할 수 있습니다. 그러나 마이크로 서비스 사용이 데이터베이스 트랜잭션을 방해하는 일반적인 시나리오에서 수행 할 수있는 작업을 살펴 보자.
옵션 1 : 가능한 경우 거래가 필요하지 않습니다
이전에 분명하고 언급되었지만 관리 할 수 있다면 이상적입니다. 구성 요소가 실제로 동일한 마이크로 서비스에 속했습니까? 아니면 거래가 불필요하게되도록 시스템을 재 설계 할 수 있습니까? 거래가 아닌 것을 받아들이는 것이 가장 저렴한 희생 일 것입니다.
옵션 2 : 대기열 사용
다른 서비스가 원하는 방식으로 성공할 것이라는 확신이 충분하면 어떤 형태의 대기열을 통해이를 호출 할 수 있습니다. 대기중인 항목은 나중에 픽업하지 않지만 해당 항목 이 대기 중인지 확인할 수 있습니다 .
예를 들어 엔터티를 삽입하고 단일 트랜잭션으로 전자 메일을 보내려고한다고 가정합니다. 메일 서버를 호출하는 대신 이메일을 테이블에 대기시킵니다.
Begin transaction
Insert entity
Insert e-mail
Commit transaction
분명한 단점은 여러 마이크로 서비스가 동일한 테이블에 액세스해야한다는 것입니다.
옵션 3 : 트랜잭션을 완료하기 직전에 외부 작업을 마지막으로 수행
이 접근법은 트랜잭션 커밋이 실패 할 가능성이 거의 없다는 가정에 기반합니다.
Begin transaction
Insert entity
Insert another entity
Make external call
Commit transaction
쿼리가 실패하면 외부 호출이 아직 수행되지 않은 것입니다. 외부 호출이 실패하면 트랜잭션은 커밋되지 않습니다.
이 방법에는 외부 호출 을 한 번만 할 수 있다는 한계가 있으며 마지막에 수행해야합니다 (예 : 쿼리에서 결과를 사용할 수 없음).
옵션 4 : 보류 상태로 물건 만들기
여기 에 게시 된 것처럼 여러 마이크로 서비스가 서로 다른 구성 요소를 작성하며 각 구성 요소는 트랜잭션 상태가 아닌 보류 상태입니다.
모든 유효성 검사가 수행되지만 결정적인 상태에서는 아무것도 생성되지 않습니다. 모든 것이 성공적으로 생성되면 각 구성 요소가 활성화됩니다. 일반적으로이 작업은 매우 간단하고 문제가 발생할 가능성이 너무 작아서 비 거래 적으로 활성화하는 것을 선호 할 수도 있습니다.
가장 큰 단점은 아마도 보류중인 항목의 존재를 설명해야한다는 것입니다. 선택 쿼리는 보류중인 데이터를 포함할지 여부를 고려해야합니다. 대부분은 무시해야합니다. 그리고 업데이트는 또 다른 이야기입니다.
옵션 5 : 마이크로 서비스가 쿼리를 공유하도록하십시오
다른 옵션은 당신을 위해 그것을하지 않습니다? 그런 다음 unorthodox를 얻자 .
회사에 따라 허용되지 않을 수 있습니다. 알고 있어요 이것은 정통입니다. 허용되지 않으면 다른 경로로 이동하십시오. 그러나 이것이 상황에 맞으면 간단하고 강력하게 문제를 해결합니다. 가장 수용 가능한 타협 일 수 있습니다.
여러 마이크로 서비스의 쿼리를 간단한 단일 데이터베이스 트랜잭션으로 전환하는 방법이 있습니다.
쿼리를 실행하지 말고 반환하십시오.
Begin transaction
Execute our own query
Make external call, receiving a query
Execute received query
Commit transaction
네트워크별로 각 마이크로 서비스는 각 데이터베이스에 액세스 할 수 있어야합니다. 향후 확장과 관련하여이 점을 명심하십시오.
트랜잭션과 관련된 데이터베이스가 동일한 서버에있는 경우 이는 일반 트랜잭션입니다. 서로 다른 서버에있는 경우 분산 트랜잭션이됩니다. 코드는 관계없이 동일합니다.
연결 유형, 매개 변수 및 연결 문자열을 포함하여 쿼리를받습니다. 플로우를 읽을 수있는 상태로 깔끔한 실행 가능 Command 클래스로 마무리 할 수 있습니다. 마이크로 서비스 호출은 트랜잭션의 일부로 실행되는 Command를 생성합니다.
연결 문자열은 원래 마이크로 서비스가 제공하는 것이므로 모든 의도와 목적을 위해 쿼리는 해당 마이크로 서비스에 의해 여전히 실행되는 것으로 간주됩니다. 우리는 단지 클라이언트 마이크로 서비스를 통해 물리적으로 라우팅하고 있습니다. 차이가 있습니까? 글쎄, 다른 쿼리와 같은 트랜잭션에 넣을 수 있습니다.
타협이 수용 가능한 경우,이 접근 방식은 마이크로 서비스 아키텍처에서 단일 응용 프로그램의 직접적인 트랜잭션 성을 제공합니다.