트랜잭션 액션의 조합
하나의 트랜잭션에 어떤 액션을 함께 지정해도 되는지. 각 서비스의 API 레퍼런스에 있는 조합 표를 읽기 위한 전제 설명
GS2가 제공하는 마이크로서비스에는 대체로 네임스페이스 설정에 transactionSettingV2라는 필드가 존재합니다.
해당 네임스페이스가 발행하는 트랜잭션을 어떻게 실행할지는 이 설정으로 정해집니다.
TransactionSettingV2는 다음과 같은 구조를 가집니다.
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| distributorNamespaceId | string | ✓ | “grn:gs2:{region}:{ownerId}:distributor:default” | ~ 1024자 | 트랜잭션 실행에 사용하는 GS2-Distributor 네임스페이스 | |
| enableParallelExecution | bool | ✓ | false | 액션을 직렬이 아닌 병렬로 실행할지 여부 |
설정하는 항목은 이 2가지뿐입니다. 트랜잭션의 실행 방법에 관한 그 밖의 항목은 권장 구성으로 고정되어 있으므로, 어느 쪽을 선택하더라도 다음 3가지는 항상 성립합니다.
이 3가지는 트랜잭션을 발행한 API의 사전 스크립트에도 적용됩니다. 예를 들어 상품 구매 시의 스크립트를 설정한 경우, 그 스크립트가 GS2의 API를 호출하여 수행한 데이터 변경이나 스크립트가 발행한 트랜잭션도 상품 구매 API가 성공했을 때 함께 반영됩니다.
트랜잭션 실행에 사용하는 GS2-Distributor 네임스페이스를 설정합니다.
용도별로 트랜잭션 실행을 나누고 싶은 경우가 아니라면, 프로젝트에 준비되는 default 네임스페이스 그대로도 문제 없습니다.
트랜잭션에 포함된 액션을 한 건씩 실행할지, 한꺼번에 동시에 실행할지를 설정합니다. 실질적으로 선택의 여지가 있는 것은 이 항목뿐입니다.
false)각 액션은 앞서 실행된 액션의 쓰기를 바탕으로 동작합니다. 액션은 검증・소비・입수 순서로 한 건씩 실행되며, 다음을 할 수 있습니다.
%{Gs2Xxx:ActionName.path[0].field}를 사용해 앞서 실행된 검증・소비 액션의 결과를 후속 검증・소비・입수 액션의 인수로 넘긴다%{...}로 참조할 수 있는 것은 검증 액션과 소비 액션의 결과뿐이며, 입수 액션의 결과는 참조할 수 없습니다.
같은 이름의 액션이 여러 개 있는 경우 먼저 실행된 것이 우선합니다.
해결할 수 없는 플레이스홀더는 인수 값으로 그대로 남기 때문에, 숫자 필드라면 검증에 실패할 수 있습니다.
그 대가는 다음과 같습니다.
각 페이즈 안에서의 실행 순서는 액션 이름, 그다음 대상 리소스로 결정됩니다. 요청에 나열한 순서가 아니므로, 재배열해서 실행 순서를 지정할 수는 없습니다. 또한 소비 액션은 이름과 관계없이 반드시 입수 액션보다 먼저 실행됩니다.
true)액션은 동일한 데이터 스냅샷에 대해 병렬로 실행됩니다. 응답 시간은 가장 느린 액션 1건분이면 되고, 액션 수의 상한도 없습니다.
그 대가는 다음과 같습니다.
database:transaction:same.resource(400)로 실패합니다%{...}는 앞선 단계(검증 → 소비 → 입수 순)의 결과만 참조할 수 있습니다. 같은 단계 안의 액션에 대한 참조는 해결되지 않고 그대로 남으며, %{...}를 포함하는 단계는 앞선 단계의 완료를 기다린 후 실행되므로 그만큼 응답 시간이 길어집니다같은 트랜잭션 안에서 두 개 이상의 액션이 같은 데이터를 갱신하지 않는다는 것을 보장할 수 있는 경우에만 활성화하십시오.
이 설정은 트랜잭션을 발행하는 시점의 동작을 바꾸지 않습니다. 같은 리소스를 대상으로 한 액션이 1건으로 통합되는 것, 조용히 버려지는 것, 에러로 거부되는 것은 직렬 실행에서도 병렬 실행에서도 동일하게 발행 시점에 일어납니다. 바뀌는 것은 액션이 실행에 도달한 이후의 동작뿐입니다. 어떤 액션을 하나의 트랜잭션에 함께 지정해도 되는지는 트랜잭션 액션의 조합을 참조하십시오.
graph TD
Start["transactionSettingV2를 설정"] --> Q3{"두 개 이상의 액션이 같은 데이터를<br/>갱신하지 않는다고 보장할 수 있는가"}
Q3 -- 보장할 수 없다 --> Sequential["enableParallelExecution = false(기본값)"]
Q3 -- 보장할 수 있다 --> Q4{"먼저 실행되는 액션의 결과를<br/>후속 액션에서 참조하는가"}
Q4 -- 같은 단계 안에서 참조한다 --> Sequential
Q4 -- 참조하지 않는다, 또는<br/>앞선 단계만 참조한다 --> Q1{"액션이 21건 이상이 되거나,<br/>응답 시간을 줄이고 싶은가"}
Q1 -- 둘 다 아니다 --> Sequential
Q1 -- 둘 중 하나에 해당한다 --> Parallel["enableParallelExecution = true"]판단하기 어려운 경우에는 기본값인 직렬 실행 그대로 두십시오. 직렬 실행은 트랜잭션을 구성하는 방식에 대한 제약이 가장 적으며, 병렬 실행에서 실패하는 조합의 대부분이 직렬 실행에서는 성립합니다.
다만 직렬 실행에서는 21건 이상의 액션을 발행할 수 없으므로, 액션 수가 상한을 넘는 데다 같은 데이터로의 쓰기도 피할 수 없는 경우에는 트랜잭션을 분할하십시오.
TransactionSettingV2가 등장하기 전에는 네임스페이스 설정의 transactionSetting으로 트랜잭션의 실행 방법을 지정했습니다.
transactionSetting은 비권장입니다. TransactionSettingV2가 존재하지 않던 시기에 생성된 네임스페이스를 위해 남아 있으며, TransactionSettingV2가 설정되어 있지 않은 동안에만 적용됩니다.
새로 생성하는 네임스페이스에서는 사용하지 마십시오.
transactionSetting은 트랜잭션 실행에 관련된 요소――자동 실행(AutoRun), 원자적 실행(AtomicCommit), GS2-Distributor를 이용한 비동기 실행, 스크립트 결과의 일괄 적용, GS2-JobQueue를 통한 입수 액션의 비동기화, 직렬 실행――를 각각 개별 항목으로 공개하고 있기 때문에 권장되지 않는 조합도 만들 수 있습니다.
그 권장 구성을 하나의 설정으로 정리한 것이 TransactionSettingV2입니다.
TransactionSettingV2를 설정하면 transactionSetting의 각 항목은 다음과 같이 고정됩니다.
transactionSetting의 항목 | TransactionSettingV2에서의 값 |
|---|---|
| enableAutoRun | true |
| enableAtomicCommit | true |
| enableSequentialExecution | enableParallelExecution의 부정 |
| transactionUseDistributor | false |
| commitScriptResultInUseDistributor | false |
| acquireActionUseJobQueue | false |
따라서 TransactionSettingV2를 사용하는 네임스페이스에서는 다음 3가지를 이용할 수 없습니다.
transactionSetting을 계속 사용하는 것은 이러한 동작에 이미 의존하고 있는 네임스페이스에 한정하십시오.
또한 예전에 이러한 설정으로 회피하던 충돌의 대부분은 직렬 실행으로 해소됩니다.
사전 스크립트의 변경과 트랜잭션의 충돌은 같은 요청 안의 갱신이 하나의 커밋으로 합류함으로써, 소비 액션과 입수 액션의 충돌이나 입수 액션끼리의 충돌은 같은 행을 여러 액션에서 갱신할 수 있음으로써 각각 회피할 필요가 없어집니다.
하나의 트랜잭션에 어떤 액션을 함께 지정해도 되는지. 각 서비스의 API 레퍼런스에 있는 조합 표를 읽기 위한 전제 설명