Documentation index for AI agents

GS2-Lottery 트랜잭션 액션

검증/소비/입수 각 트랜잭션 액션의 사양

액션의 조합과 동시 실행

모든 서비스에 공통되는 전제는 트랜잭션 액션의 조합에 정리되어 있습니다. 먼저 그쪽을 읽어 주십시오. 이 절의 나머지는 GS2-Lottery 고유의 내용입니다.

GS2-Lottery가 트랜잭션에 지정할 수 있는 액션은 2가지입니다. 추첨은 하나씩, 당첨된 경품을 산출하여 그것을 자신의 트랜잭션으로 발행합니다. 10연 추첨이라면 10개의 안쪽 트랜잭션이 됩니다. GS2-Lottery를 사용할 때 가장 주의가 필요한 것이 이 점으로, 아래의 「경품이 배분하는 것」에 정리했습니다.

GS2-Lottery 자체 안에서 무엇을 건드리는지는 경품 테이블의 종류에 따릅니다. 일반 경품 테이블은 사용자별 상태를 갖지 않지만, 박스 경품 테이블은 네임스페이스·사용자·경품 테이블의 조합으로 결정되는 박스를 가집니다.

조작같은 행을 겹쳤을 때중첩 너머다른 대상이 되는 경계
추첨
DrawByUserId
추첨 모델과 config가 같으면 통합되어 추첨 횟수가 합산된다. 같은 박스에 대한 config가 다른 추첨은 실패한다박스 경품 테이블이면 실패한다. 일반 경품 테이블이면 충돌하지 않는다네임스페이스·사용자·추첨 모델·config
박스의 리셋
ResetBoxByUserId
1건으로 통합된다실패한다네임스페이스·사용자·경품 테이블

일반 경품 테이블은 사용자별 상태를 갖지 않으므로, 하나의 트랜잭션에서 몇 번 추첨해도 여기에서는 충돌하지 않습니다. 추첨이 배분하는 것은 별개의 이야기로, 아래와 같습니다.

추첨과 리셋은 행이 다르고, 같은 박스에 대해서는 경계가 같으므로 하나의 트랜잭션에 넣을 수 없습니다. 박스를 리셋한 뒤 추첨하는 흐름도 충돌 문제를 별개로 하고 성립하지 않습니다. 추첨은 트랜잭션 시작 시점의 상태에서 이루어지므로 리셋이 보이지 않기 때문입니다.

경품이 배분하는 것

추첨의 경품은 각각 안쪽 트랜잭션으로 발행되므로, 그것들이 속한 서비스의 제한이 그대로 해당되며, 아래의 「중첩된 트랜잭션에 주의」도 해당됩니다. 추첨이 두 번 있으면 안쪽 트랜잭션도 두 개이며, 그것들은 서로도 통합되지 않습니다.

GS2-Lottery에서 가장 주의해야 할 것이 이 점입니다. 10연 추첨이나 하나의 트랜잭션에서의 복수 추첨에서는, 같은 아이템·같은 통화·같은 스테이터스를 배분하는 경품이 두 개 나오는 일이 쉽게 일어납니다. 그것이 허용되는지를 결정하는 것은 GS2-Lottery가 아니라 경품이 속한 서비스입니다. 그 서비스들의 중첩에 관한 기술을 확인해 주십시오.

또한 경품별 추첨 상한에 도달한 경품은 당첨되지 않고, 대신 다른 경품이 추첨됩니다. 상한에 도달해도 트랜잭션이 실패하는 것은 아닙니다.

중첩된 트랜잭션에 주의

안쪽에서 추첨된 박스와 바깥쪽에서 리셋된 같은 박스가 충돌하여 트랜잭션이 실패합니다.

제한을 회피하고 싶은 경우

추첨도 박스의 리셋도 획득 액션이므로, 「박스에서의 추첨과 리셋의 공존」 「config가 다른 추첨의 복수 지정」은 모두 acquireActionUseJobQueue를 활성화하면 해소할 수 있습니다. enableAtomicCommit을 비활성화하면 서로 다른 추첨의 경품도 한 번의 기록에 모이지 않게 됩니다.

동시 실행과 재시도

일반 경품 테이블에서의 추첨은 GS2-Lottery 자체 안에서는 동시 실행 요청과 충돌하지 않습니다. 충돌하는지는 경품이 배분하는 것에 따라 결정됩니다.

박스에서의 추첨과 박스의 리셋은 둘 다 박스를 다시 쓰므로, 동시에 실행하면 나중에 확정된 쪽이 충돌(409)이 됩니다. 이것이 같은 경품을 박스에서 이중으로 꺼내지 못하게 하는 구조입니다. 재시도하면 최신 박스 상태로 다시 판정됩니다.


Acquire Action

입수 액션

Gs2Lottery:DrawByUserId

사용자 ID를 지정하여 추첨을 실행

추첨 모델의 설정에 따라 지정한 사용자의 추첨을 실행합니다.
추첨은 두 가지 방식을 지원합니다: 배출 확률 테이블 모드(사전에 정의된 확률 테이블 사용)와 스크립트 모드(GS2-Script로 경품을 결정).
박스 추첨 모드에서는 배출된 경품이 박스에서 삭제되어 다시 배출되지 않습니다. 박스가 비어 있는 경우 Empty 오류가 반환됩니다.
배출된 경품은 트랜잭션으로 발행됩니다.

수량 지정 가능한 액션: 예

반전 가능한 액션: 아니오

타입활성화 조건필수기본값값 제한설명
namespaceNamestring
~ 128자네임스페이스 이름
lotteryNamestring
~ 128자추첨 모델 이름
추첨 모델 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다.
userIdstring
~ 128자사용자ID
#{userId}로 설정하면 로그인 중인 사용자ID로 치환됩니다.
countint
1 ~ 1000추첨 횟수
configList<Config>[]0 ~ 1000 items트랜잭션의 플레이스홀더에 적용하는 설정값
timeOffsetTokenstring~ 1024자타임 오프셋 토큰
{
    "action": "Gs2Lottery:DrawByUserId",
    "request": {
        "namespaceName": "[string]네임스페이스 이름",
        "lotteryName": "[string]추첨 모델 이름",
        "userId": "[string]사용자ID",
        "count": "[int]추첨 횟수",
        "config": [
            {
                "key": "[string]이름",
                "value": "[string]값"
            }
        ],
        "timeOffsetToken": "[string]타임 오프셋 토큰"
    }
}
action: Gs2Lottery:DrawByUserId
request:
  namespaceName: "[string]네임스페이스 이름"
  lotteryName: "[string]추첨 모델 이름"
  userId: "[string]사용자ID"
  count: "[int]추첨 횟수"
  config: 
    - key: "[string]이름"
      value: "[string]값"
  timeOffsetToken: "[string]타임 오프셋 토큰"
transaction.service("lottery").acquire.draw_by_user_id({
    namespaceName="[string]네임스페이스 이름",
    lotteryName="[string]추첨 모델 이름",
    userId="[string]사용자ID",
    count="[int]추첨 횟수",
    config={
        {
            key="[string]이름",
            value="[string]값"
        }
    },
    timeOffsetToken="[string]타임 오프셋 토큰",
})

Gs2Lottery:ResetBoxByUserId

사용자 ID를 지정하여 박스를 리셋

지정한 사용자의 박스를 초기 상태로 리셋하고, 배출된 모든 경품을 박스로 되돌립니다.

수량 지정 가능한 액션: 아니오

반전 가능한 액션: 아니오

타입활성화 조건필수기본값값 제한설명
namespaceNamestring
~ 128자네임스페이스 이름
네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다.
prizeTableNamestring
~ 128자배출 확률 테이블 이름
userIdstring
~ 128자사용자ID
#{userId}로 설정하면 로그인 중인 사용자ID로 치환됩니다.
timeOffsetTokenstring~ 1024자타임 오프셋 토큰
{
    "action": "Gs2Lottery:ResetBoxByUserId",
    "request": {
        "namespaceName": "[string]네임스페이스 이름",
        "prizeTableName": "[string]배출 확률 테이블 이름",
        "userId": "[string]사용자ID",
        "timeOffsetToken": "[string]타임 오프셋 토큰"
    }
}
action: Gs2Lottery:ResetBoxByUserId
request:
  namespaceName: "[string]네임스페이스 이름"
  prizeTableName: "[string]배출 확률 테이블 이름"
  userId: "[string]사용자ID"
  timeOffsetToken: "[string]타임 오프셋 토큰"
transaction.service("lottery").acquire.reset_box_by_user_id({
    namespaceName="[string]네임스페이스 이름",
    prizeTableName="[string]배출 확률 테이블 이름",
    userId="[string]사용자ID",
    timeOffsetToken="[string]타임 오프셋 토큰",
})