Documentation index for AI agents

GS2-Lottery トランザクションアクション

検証/消費/入手の各トランザクションアクションの仕様

アクションの組み合わせと同時実行

すべてのサービスに共通する前提は トランザクションアクションの組み合わせ にまとめています。先にそちらを読んでください。この節の残りは GS2-Lottery 固有の内容です。

GS2-Lottery がトランザクションに指定できるアクションは 2 つです。抽選は 1 つずつ、当選した景品を算出してそれを自身のトランザクションとして発行します。10 連の抽選なら 10 個の内側のトランザクションになります。GS2-Lottery を使ううえで最も注意が必要なのはこの点で、下記「景品が配るもの」にまとめています。

GS2-Lottery 自身の中で何を触るかは景品テーブルの種類によります。通常の景品テーブルはユーザーごとの状態を持ちませんが、箱の景品テーブルはネームスペース・ユーザー・景品テーブルの組で決まる箱を持ちます。

操作同じ行を重ねたとき入れ子越し別の対象になる境界
抽選
DrawByUserId
抽選モデルと config が同じなら統合され、抽選回数が合算される。同じ箱に対する config が違う抽選は失敗する箱の景品テーブルなら失敗する。通常の景品テーブルなら衝突しないネームスペース・ユーザー・抽選モデル・config
箱のリセット
ResetBoxByUserId
1 件に統合される失敗するネームスペース・ユーザー・景品テーブル

通常の景品テーブルはユーザーごとの状態を持たないため、1 つのトランザクションで何度抽選してもここでは衝突しません。抽選が配るものは別の話で、下記のとおりです。

抽選とリセットは行が違い、同じ箱に対しては境界が同じなので、1 つのトランザクションに入れることはできません。箱をリセットしてから抽選する流れも、衝突の問題を別にして成立しません。抽選はトランザクション開始時点の状態から行われるため、リセットが見えていないからです。

景品が配るもの

抽選の景品はそれぞれ内側のトランザクションとして発行されるため、それらが属するサービスの制限がそのまま当てはまり、下記「入れ子になったトランザクションに注意」も当てはまります。抽選が 2 回あれば内側のトランザクションも 2 つで、それらは互いにも統合されません。

GS2-Lottery で最も注意すべきなのがこの点です。10 連の抽選や、1 つのトランザクションでの複数の抽選では、同じアイテム・同じ通貨・同じステータスを配る景品が 2 つ出ることが容易に起こります。それが許されるかどうかを決めるのは GS2-Lottery ではなく、景品が属するサービスです。それらのサービスの入れ子に関する記述を確認してください。

なお景品ごとの抽選上限に達している景品は当選せず、代わりに別の景品が抽選されます。上限に達してもトランザクションが失敗するわけではありません。

入れ子になったトランザクションに注意

内側から抽選された箱と、外側からリセットされた同じ箱が衝突して、トランザクションが失敗します。

制限を回避したい場合

抽選も箱のリセットも入手アクションなので、「箱からの抽選とリセットの同居」「config が違う抽選の複数指定」はどちらも acquireActionUseJobQueue を有効にすれば解消できます。enableAtomicCommit を無効にすると、別々の抽選の景品も 1 回の書き込みに集まらなくなります。

同時実行とリトライ

通常の景品テーブルからの抽選は、GS2-Lottery 自身の中では同時実行のリクエストとコンフリクトしません。コンフリクトするかどうかは、景品が配るものによって決まります。

箱からの抽選と箱のリセットはどちらも箱を書き換えるため、同時に実行すると後から確定した側がコンフリクト (409) になります。これが同じ景品を箱から二重に取り出さないための仕組みです。リトライすると最新の箱の状態で判定し直されます。


Acquire Action

入手アクション

Gs2Lottery:DrawByUserId

ユーザーIDを指定して抽選を実行

抽選モデルの設定に基づいて、指定されたユーザーの抽選を実行します。
抽選は2つの方式をサポートします:排出確率テーブルモード(事前定義された確率テーブルを使用)とスクリプトモード(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]タイムオフセットトークン",
})