> For the complete documentation index, see [llms.txt](/llms.txt)

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

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




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

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

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

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

操作 | 同じ行を重ねたとき | 入れ子越し | 別の対象になる境界 | 直列実行モード有効時
--- | --- | --- | --- | ---
抽選<br>`DrawByUserId` | 抽選モデルと config が同じなら統合され、抽選回数が合算される。同じ箱に対する config が違う抽選は失敗する | 箱の景品テーブルなら失敗する。通常の景品テーブルなら衝突しない | ネームスペース・ユーザー・抽選モデル・config | 箱の景品テーブルは変わらず失敗する。抽選は当選した景品をリスト内の位置指定で取り除くため、その除去を他の書き込みと同じ行に畳み込めないことは直列実行モードでも解消しない。同じトランザクション内でも入れ子越しでも同様。通常の景品テーブルはもともと影響を受けないので変わらない
箱のリセット<br>`ResetBoxByUserId` | 1 件に統合される | 失敗する | ネームスペース・ユーザー・景品テーブル | 変わらず失敗する。リセットは景品テーブルの箱を削除したうえで自分でそれを読み直すため、同じ箱に対する別のリセットとも抽選ともまとめられない

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

抽選とリセットは行が違い、同じ箱に対しては境界が同じなので、1 つのトランザクションに入れることはできません。箱をリセットしてから抽選する流れも、衝突の問題を別にして成立しません。抽選はトランザクション開始時点の状態から行われるため、リセットが見えていないからです。**直列実行モード（`enableSequentialExecution` または `TransactionSettingV2`）を有効にすると、後半の問題はなくなります。抽選は同じトランザクション内で先に実行されたアクションの書き込み（リセットを含む）を見られるようになるためです。前半の問題はなくなりません。箱への抽選は当選した景品をリスト内の位置指定で取り除く処理なので、それを同じ行への他の書き込みと畳み込むことは相変わらずできず、同じ箱への抽選とリセットを 1 つのトランザクションに入れることは引き続き失敗します。**

### 景品が配るもの

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

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

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

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

内側から抽選された箱と、外側からリセットされた同じ箱が衝突して、トランザクションが失敗します。 直列実行モードでもこれは変わりません。この失敗は抽選のリスト位置指定の除去が同じ行への他の書き込みと畳み込めないことから来ており、実行モードの影響を受けないためです。

### 制限を回避したい場合

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

### 同時実行とリトライ

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

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

---




## Acquire Action

入手アクション

### Gs2Lottery:DrawByUserId

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

抽選モデルの設定に基づいて、指定されたユーザーの抽選を実行します。<br>
抽選は2つの方式をサポートします：排出確率テーブルモード（事前定義された確率テーブルを使用）とスクリプトモード（GS2-Script で景品を決定）。<br>
ボックス抽選モードでは、排出された景品はボックスから削除され再度排出されません。ボックスが空の場合は Empty エラーが返されます。<br>
排出された景品はトランザクションとして発行されます。

**数量指定可能なアクション：はい**

**反転可能なアクション：いいえ**

|  | 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128文字 | ネームスペース名 |
| lotteryName | string |  | ✓|  |  ~ 128文字 | 抽選モデル名<br>抽選モデル固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。 |
| userId | string |  | ✓|  |  ~ 128文字 | ユーザーID<br>`#{userId}` と設定することでログイン中のユーザーIDに置換されます。 |
| count | int |  | ✓|  | 1 ~ 1000 | 抽選回数 |
| config | [List&lt;Config&gt;](../sdk/#config) |  | | [] | 0 ~ 1000 items | トランザクションのプレースホルダに適用する設定値 |
| timeOffsetToken | string |  | |  |  ~ 1024文字 | タイムオフセットトークン |




**JSON**
```json
{
    "action": "Gs2Lottery:DrawByUserId",
    "request": {
        "namespaceName": "[string]ネームスペース名",
        "lotteryName": "[string]抽選モデル名",
        "userId": "[string]ユーザーID",
        "count": "[int]抽選回数",
        "config": [
            {
                "key": "[string]名前",
                "value": "[string]値"
            }
        ],
        "timeOffsetToken": "[string]タイムオフセットトークン"
    }
}
```

**YAML**
```yaml

action: Gs2Lottery:DrawByUserId
request:
  namespaceName: "[string]ネームスペース名"
  lotteryName: "[string]抽選モデル名"
  userId: "[string]ユーザーID"
  count: "[int]抽選回数"
  config: 
    - key: "[string]名前"
      value: "[string]値"
  timeOffsetToken: "[string]タイムオフセットトークン"
```

**GS2-Script**
```lua

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を指定してボックスをリセット<br>

指定されたユーザーのボックスを初期状態にリセットし、排出済みのすべての景品をボックスに戻します。

**数量指定可能なアクション：いいえ**

**反転可能なアクション：いいえ**

|  | 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128文字 | ネームスペース名<br>ネームスペース固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。 |
| prizeTableName | string |  | ✓|  |  ~ 128文字 | 排出確率テーブル名 |
| userId | string |  | ✓|  |  ~ 128文字 | ユーザーID<br>`#{userId}` と設定することでログイン中のユーザーIDに置換されます。 |
| timeOffsetToken | string |  | |  |  ~ 1024文字 | タイムオフセットトークン |




**JSON**
```json
{
    "action": "Gs2Lottery:ResetBoxByUserId",
    "request": {
        "namespaceName": "[string]ネームスペース名",
        "prizeTableName": "[string]排出確率テーブル名",
        "userId": "[string]ユーザーID",
        "timeOffsetToken": "[string]タイムオフセットトークン"
    }
}
```

**YAML**
```yaml

action: Gs2Lottery:ResetBoxByUserId
request:
  namespaceName: "[string]ネームスペース名"
  prizeTableName: "[string]排出確率テーブル名"
  userId: "[string]ユーザーID"
  timeOffsetToken: "[string]タイムオフセットトークン"
```

**GS2-Script**
```lua

transaction.service("lottery").acquire.reset_box_by_user_id({
    namespaceName="[string]ネームスペース名",
    prizeTableName="[string]排出確率テーブル名",
    userId="[string]ユーザーID",
    timeOffsetToken="[string]タイムオフセットトークン",
})
```


---



