트랜잭션 액션의 조합
각 서비스의 API 레퍼런스에는 「하나의 트랜잭션에 지정할 수 있는 조합」이라는 표가 있습니다. 이 페이지는 그 표를 읽기 위한 전제를 정리한 것입니다.
액션의 「종별」
각 서비스의 액션 표에 있는 「종별」은 그 액션을 트랜잭션의 검증·소비·획득 중 어느 목록에 둘 수 있는지를 나타냅니다.
액션의 이름이나 실제 효과와 일치하지 않는 경우가 있습니다. 이름이 Verify라도 소비 액션이거나, 아무것도 업데이트하지 않는데 획득 액션인 경우가 있습니다.
각 서비스의 표를 읽는 법
각 서비스의 페이지에는 그 서비스의 조작을 나열한 표가 있습니다.
| 열 | 의미 |
|---|---|
| 조작 | 묶이는 단위. 같은 행에 나열된 조작끼리는 1건으로 통합됩니다 |
| 같은 행을 겹쳤을 때 | 그 행의 조작을 하나의 트랜잭션에 여러 개 지정한 결과 |
| 중첩 너머 | 같은 대상에 대한 업데이트가 안쪽 트랜잭션에서도 도착한 경우의 결과 |
| 다른 대상이 되는 경계 | 여기가 다르면 다른 대상이므로, 몇 개를 나열해도 충돌하지 않습니다 |
같은 경계 안에서 서로 다른 행의 조작을 겹치면 트랜잭션이 실패합니다. 행이 나뉘어 있는 것은 값을 합성하는 방법을 정의할 수 없기 때문입니다.
결과 칸에는 다음 용어를 사용합니다.
| 용어 | 의미 |
|---|---|
| 통합된다 | 1건으로 묶여 값이 합산 또는 결합됩니다 |
| 같은 값이면 통합 | 같은 값을 지정했다면 1건이 됩니다. 값이 다르면 발행 시에 오류가 됩니다 |
| 먼저 지정한 쪽이 남음 | 오류가 되지 않고 두 번째 이후가 조용히 버려집니다 |
| 실패한다 | 트랜잭션이 실패합니다(400). 재시도해도 해결되지 않습니다 |
| 충돌하지 않는다 | 겹쳐도 됩니다 |
이 5개 용어로 부족한 경우에는, 셀에 그 서비스 고유의 결과가 그대로 쓰입니다. 「나중에 도착한 쪽의 값으로 덮어써진다」 「진행을 건드리지 않는다」와 같은 기술이 그것입니다.
검증 액션은 읽기만 하므로 어떤 업데이트와 함께 두어도 됩니다. 검증 행만은 위 규칙의 예외입니다.
검증 액션끼리 겹친 경우, 대상·검증 타입·임계값이 모두 같은 것만이 하나로 묶입니다. 어느 하나라도 다르면 각각 독립적으로 판정됩니다.
묶였을 때의 취급은 두 가지가 있으며, 액션에 따라 다릅니다.
| 취급 | 결과 |
|---|---|
| 임계값이 합산된다 | 완전히 같은 검증을 두 번 작성하면, 임계값이 2배인 검증 1건이 됩니다 |
| 두 번째가 버려진다 | 완전히 같은 검증이므로 결과는 달라지지 않습니다 |
어느 쪽이 되는지는 각 서비스의 페이지에 쓰여 있습니다. multiplyValueSpecifyingQuantity에 false를 명시한 액션은 그룹화 대상에서 제외되어 항상 각각 독립적으로 판정됩니다.
「같은 행을 겹쳤을 때」 칸에 있는 「발행 시에 오류」는 트랜잭션을 구성하는 시점에 거부됩니다. 중첩 너머의 경우에는 그 검사가 작동하지 않으므로, 같은 불일치가 실행 시의 실패가 됩니다. 둘 다 400이며 재시도해도 해결되지 않습니다.
해당하는 행을 찾을 수 없는 경우, 그 조합은 지정해도 됩니다. 「쓰여 있지 않으니 알 수 없다」가 아니라 「제한이 없다」라고 읽어 주십시오. 다른 서비스의 액션끼리도 충돌하지 않습니다.
실패의 종류와 재시도
| 표의 기술 | 언제 거부되는가 | 상태 |
|---|---|---|
| 트랜잭션이 실패합니다 | 실행 시 | 400 |
| 발행 시에 오류가 됩니다 | 실행보다 앞서, 트랜잭션을 구성하는 시점 | 400 |
둘 다 트랜잭션 구성 자체의 문제입니다. 재시도해도 해결되지 않습니다.
충돌(409)은 상태가 경합했을 뿐이므로 재시도해도 됩니다. 다만 서비스에 따라서는 재시도해도 해소되지 않는 충돌이 있습니다. 해당하는 경우에는 각 서비스의 페이지에 쓰여 있습니다.
중첩된 트랜잭션
액션 중에는 그 액션 자신이 다시 별도의 트랜잭션을 발행하는 것이 있습니다. 다음이 해당됩니다.
추첨(GS2-Lottery), 교환(GS2-Exchange), 강화와 해방(GS2-Enhance), 보상 수령(GS2-Mission / GS2-LoginReward / GS2-Idle / GS2-Ranking2), 메시지 개봉(GS2-Inbox), 시리얼 코드 사용(GS2-SerialKey), 진열대에서의 구매(GS2-Showcase), 노드의 해방(GS2-SkillTree), 배율 적용(GS2-Experience / GS2-Grade), 스크립트 실행(GS2-Script), 스테이트 머신의 시작(GS2-StateMachine)
각 서비스의 조합 표는 하나의 트랜잭션에 직접 지정한 액션끼리의 이야기입니다. 안쪽 트랜잭션이 발행하는 업데이트는 그것들과 통합되지 않습니다. 이것은 두 가지 형태로 일어납니다.
- 바깥쪽과 안쪽 — 트랜잭션에 직접 지정한 액션과, 안쪽 트랜잭션이 발행하는 업데이트가 같은 대상을 건드림
- 안쪽끼리 — 두 개 이상의 중첩 액션이 각각의 안쪽에서 같은 대상을 건드림
후자를 놓치기 쉽습니다. 10연 추첨, 여러 스텝의 로그인 보너스를 한꺼번에 수령, 진열대에서 2개 상품을 구매하는 구성은 모두 이 형태가 됩니다. 안쪽끼리도 통합되지 않으므로, 바깥쪽과 안쪽의 경우와 완전히 같은 취급입니다.
둘 다 그 대상이 두 개의 기록을 허용하지 않는 경우에는 트랜잭션이 실패합니다. 이러한 충돌은 잘못된 트랜잭션으로 취급되므로, 재시도해도 해소되지 않습니다.
중첩된 액션의 내용을 조사하는 방법
중첩된 액션이 무엇을 배분(소비)하는지는 그 액션이 참조하는 마스터 데이터로 결정됩니다. 추첨이라면 경품 테이블, 미션이라면 보상, 시리얼 코드라면 캠페인, 로그인 보너스라면 보너스 모델입니다.
배분되는 것의 대부분은 GS2-Inventory의 아이템, GS2-Money2의 통화, GS2-Experience의 경험치입니다. 같은 대상을 바깥쪽에서도 건드리고 있지 않은지를 각 서비스의 페이지에서 확인해 주십시오.
제한을 회피하고 싶은 경우
지금까지의 제한은 트랜잭션을 한 번의 원자적인 커밋으로 실행하는 데에서 비롯됩니다. 실행 방침은 그 트랜잭션을 발행하는 네임스페이스의 트랜잭션 설정에서 변경할 수 있습니다. 안쪽 트랜잭션에서 도착하는 업데이트와의 충돌도, 바깥쪽 트랜잭션을 발행하는 네임스페이스에서 이 설정을 바꾸면 회피할 수 있습니다.
enableAtomicCommit을 비활성화하면 액션이 한꺼번에가 아니라 하나씩 실행되므로, 같은 대상을 여러 액션이 업데이트해도 충돌하지 않습니다. 그 대신 트랜잭션 전체가 일괄로 성공·실패하는 보장이 없어지고, 도중까지 적용된 상태가 있을 수 있습니다.acquireActionUseJobQueue를 활성화하면 원자적인 커밋은 유지한 채, 획득 액션이 2개 이상일 때 그것들을 GS2-JobQueue를 거쳐 하나씩 실행하게 됩니다. 검증 액션과 소비 액션의 원자성은 유지됩니다. 그 대신 획득 액션이 비동기가 되어, 트랜잭션의 응답 시점에는 반영이 완료되지 않습니다.
둘 다 네임스페이스의 설정으로, 그 네임스페이스가 발행하는 모든 트랜잭션에 영향을 줍니다. 유지하고 싶은 보장과 비교하여 선택해 주십시오.
acquireActionUseJobQueue가 분리할 수 있는 것은 획득 액션끼리뿐입니다. 획득 액션과 소비 액션의 조합으로 실패하는 경우에는 효과가 없습니다. 어느 쪽에 해당하는지는 각 서비스의 페이지에 쓰여 있습니다.
「발행 시에 오류가 됩니다」라고 쓰여 있는 것은 어느 설정으로도 해소되지 않습니다. 실행 방침보다 앞서, 트랜잭션을 구성하는 시점의 판정이기 때문입니다.
실행 순서와, 각 액션이 보는 상태
검증 액션, 소비 액션, 획득 액션의 순으로 실행됩니다. 이 순서는 어떤 설정에서도 달라지지 않습니다.
기본값인 원자적인 커밋에서는 모든 액션이 트랜잭션 시작 시점의 상태를 기준으로 판정됩니다. 같은 트랜잭션의 다른 액션이 수행한 변경은 어느 액션에서도 보이지 않습니다. 그 때문에 「삭제한 결과를 생성 액션이 본다」 「업데이트한 결과를 검증 액션이 본다」와 같은 구성은 할 수 없습니다.
enableAtomicCommit을 비활성화한 경우와 acquireActionUseJobQueue를 활성화한 경우에는, 획득 액션이 하나씩 실행되며 각각이 직전까지의 결과를 봅니다. 전자에서는 소비 액션도 하나씩 실행되므로, 획득 액션은 그 결과도 봅니다.
다만 검증 액션과 소비 액션이 획득 액션보다 뒤에 실행되는 일은 없습니다. 「획득한 것을 같은 트랜잭션에서 소비한다」와 같은 구성은 어떤 설정에서도 할 수 없습니다. 순서가 필요한 경우에는 트랜잭션을 나누어 주십시오.