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

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

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




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

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

GS2-Limit のトランザクションアクションは、ネームスペース・ユーザー・回数制限の種類・カウンター名の組で決まる 1 つのカウンターを対象にします。

操作 | 同じ行を重ねたとき | 入れ子越し | 別の対象になる境界 | 直列実行モード有効時
--- | --- | --- | --- | ---
カウントアップ・カウントダウン<br>`CountUpByUserId` `CountDownByUserId` | 混在してよい。統合され、値が合算される。ただし `maxValue` が違うカウントアップを並べると発行時にエラー | 合算される | ネームスペース・ユーザー・回数制限の種類・カウンター名 | 変わらない。もともと合算されて成立する
カウンターの削除<br>`DeleteCounterByUserId` | 1 件に統合される | 失敗する | ネームスペース・ユーザー・回数制限の種類・カウンター名 | 成立する。入れ子越しでも 1 件に統合され、同じトランザクションでカウントアップと同居できるようになる（下記参照）
検証<br>`VerifyCounterByUserId` | まったく同じ検証は 1 件にまとめられる。`multiplyValueSpecifyingQuantity` を明示的に `true` にしたときだけしきい値が合算される (検証タイプは問わない。しきい値を「1 個あたりの量」として宣言したことになるため)。回数が違う検証はそれぞれ判定される | 読み取りだけなので衝突しない | カウンター・検証タイプ・回数 | 変わらない。読み取りだけなのでもともと衝突しない

カウントアップとカウントダウンが同じ行なのは、どちらも同じ値への純粋な増分として書き込まれるからです。混在させてかまいません。結果は統合後の合計に対して判定されます。カウントは 0 を下回れず、回数制限の種類に設定された上限も超えられないので、単独なら収まるカウントアップでも他のカウントアップと合わさると弾かれることがあります。

**上限が違うカウントアップは、同じカウンターに並べられません。** 上限が食い違ったまま合算すると、厳しい上限が消えたり緩い加算が厳しい上限で弾かれたりするため、`maxValue` が違うカウントアップを同じカウンターに指定すると発行時にエラーになります。分けて指定してください。

カウンターの削除は値を変えるのではなくカウンターそのものを消すため、同じカウンターを触る他のアクションと同居できません。カウンターをリセットしてから数え直したい場合は、トランザクションを分けてください。

**直列実行モード（`enableSequentialExecution` または `TransactionSettingV2`）を有効にすると、削除をカウントアップと同居させられるようになります。順序は選べません。カウントアップは消費アクション、削除は入手アクションなので、削除は必ず後に実行され、直前まで数えた分をまとめて削除します。削除でカウンターを新しく始めてから同じトランザクションで数え直すことはできません。**

**カウンターは「これまで何回やったか」という状態なので、しきい値は既定では数量に応じて変化しません。** 数量ぶん増えるのは対になるカウントアップのほうです。`multiplyValueSpecifyingQuantity` を明示的に `true` にしたときだけ、しきい値が合算され数量に応じて倍になります。**そのうえで合算されるのは、合算すると検証が厳しくなる向きだけです。** `greater` `greaterEqual` はしきい値が大きいほど満たしにくいので、同じ検証を重ねると条件が厳しくなり、`multiplyValueSpecifyingQuantity` を指定すれば購入数量に応じて倍にもなります。`less` `lessEqual` はしきい値が大きいほど満たしやすいため、合算すると検証を重ねるほど・数量を増やすほど回数制限を回避できてしまいます。これらはまとめられるだけで合算されず、数量による倍率もかかりません。`equal` `notEqual` は合算すると別の主張になるので、同じくまとめられるだけです。

検証アクションはトランザクション開始時点のカウンターを見ます。同じトランザクションで到達するカウントを検証することはできません。

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

カウントアップ・カウントダウンは入れ子越しでも安全です。どちらの経路から届いても 1 回の更新にまとまります。

カウンターの削除は違います。削除が内側から届き、同じカウンターを外側から数えている場合は、トランザクションが失敗します。

**直列実行モードを有効にすると、計数がカウントアップの場合はこの失敗もなくなります。内側のトランザクションは外側と同じ直列実行の区間で実行されるようになり、カウントアップの後に削除が続く形は衝突する代わりに組み合わされます。削除が先に実行されてカウントダウンが続く場合は、まとめられずトランザクションが失敗します。**

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

カウントダウンとカウンターの削除は入手アクション、カウントアップは消費アクションです。削除とカウントダウンの衝突は `acquireActionUseJobQueue` を有効にすれば解消できますが、削除とカウントアップの同居は `enableAtomicCommit` を無効にしないと解消しません。

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

カウントアップ・カウントダウンは、結果が範囲に収まるかぎり、同時実行のリクエストが何本重なってもコンフリクトしません。同時に走ったカウントアップの合計が上限を超えた場合や、カウントダウンの合計が 0 を下回る場合にコンフリクト (409) になります。リトライすると最新のカウントで判定し直されます。

カウンターは設定に従って定期的にリセットされます。リセット境界にちょうど重なったリクエストはコンフリクト (409) になることがあります。リセットが落ち着いてからリトライすれば成功します。

---


## Verify Action

検証アクション

### Gs2Limit:VerifyCounterByUserId

ユーザーIDを指定してカウンター値を検証<br>

指定されたユーザーのカウンター値が指定された条件を満たすことを検証します。<br>
6つの比較演算子をサポートします：less、lessEqual、greater、greaterEqual、equal、notEqual。

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

|  | 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128文字 | ネームスペース名<br>ネームスペース固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。 |
| userId | string |  | ✓|  |  ~ 128文字 | ユーザーID<br>`#{userId}` と設定することでログイン中のユーザーIDに置換されます。 |
| limitName | string |  | ✓|  |  ~ 128文字 | 回数制限モデル名<br>このカウンターが属する回数制限モデルの名前です。このカウンターの値に適用されるリセットスケジュール（毎日、毎週、毎月など）を決定します。 |
| counterName | string |  | ✓|  |  ~ 128文字 | カウンターの名前<br>回数制限モデル内でこのカウンターを一意に識別する名前です。同じ回数制限モデルを異なる名前の複数のカウンターで共有でき、個別の回数制限モデルを作成せずに別々の使用回数追跡（例：クエストごとや商品ごとに1カウンター）が可能です。 |
| verifyType | 文字列列挙型<br>enum {<br>"less",<br>"lessEqual",<br>"greater",<br>"greaterEqual",<br>"equal",<br>"notEqual"<br>}<br> |  | ✓|  |  | 検証の種類less: カウンター値が指定値未満であること / lessEqual: カウンター値が指定値以下であること / greater: カウンター値が指定値超過であること / greaterEqual: カウンター値が指定値以上であること / equal: カウンター値が指定値と一致すること / notEqual: カウンター値が指定値と一致しないこと /  |
| count | int |  | | 0 | 0 ~ 2147483646 | カウント値<br>このカウンターの現在の使用回数です。countUp操作でインクリメントされ、その際に指定された最大値と比較されます。回数制限モデルのリセットタイミングに達すると自動的にゼロにリセットされます。 |
| multiplyValueSpecifyingQuantity | bool |  | | true |  | 数量指定した際に、検証に使用する値も乗算するか |
| timeOffsetToken | string |  | |  |  ~ 1024文字 | タイムオフセットトークン |




**JSON**
```json
{
    "action": "Gs2Limit:VerifyCounterByUserId",
    "request": {
        "namespaceName": "[string]ネームスペース名",
        "userId": "[string]ユーザーID",
        "limitName": "[string]回数制限モデル名",
        "counterName": "[string]カウンターの名前",
        "verifyType": "[string]検証の種類",
        "count": "[int]カウント値",
        "multiplyValueSpecifyingQuantity": "[bool]数量指定した際に、検証に使用する値も乗算するか",
        "timeOffsetToken": "[string]タイムオフセットトークン"
    }
}
```

**YAML**
```yaml

action: Gs2Limit:VerifyCounterByUserId
request:
  namespaceName: "[string]ネームスペース名"
  userId: "[string]ユーザーID"
  limitName: "[string]回数制限モデル名"
  counterName: "[string]カウンターの名前"
  verifyType: "[string]検証の種類"
  count: "[int]カウント値"
  multiplyValueSpecifyingQuantity: "[bool]数量指定した際に、検証に使用する値も乗算するか"
  timeOffsetToken: "[string]タイムオフセットトークン"
```

**GS2-Script**
```lua

transaction.service("limit").verify.verify_counter_by_user_id({
    namespaceName="[string]ネームスペース名",
    userId="[string]ユーザーID",
    limitName="[string]回数制限モデル名",
    counterName="[string]カウンターの名前",
    verifyType="[string]検証の種類",
    count="[int]カウント値",
    multiplyValueSpecifyingQuantity="[bool]数量指定した際に、検証に使用する値も乗算するか",
    timeOffsetToken="[string]タイムオフセットトークン",
})
```


---

## Consume Action

消費アクション

### Gs2Limit:CountUpByUserId

ユーザーIDを指定してカウントアップ<br>

指定されたユーザーのカウンターを指定されたカウントアップ値だけ増加させます。<br>
maxValue が指定された場合、カウンターはその上限を超えません。操作が最大値を超える場合は Overflow エラーが返されます。<br>
カウンターがまだ存在しない場合、自動的に作成されます。

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

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

|  | 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128文字 | ネームスペース名<br>ネームスペース固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。 |
| limitName | string |  | ✓|  |  ~ 128文字 | 回数制限モデル名<br>このカウンターが属する回数制限モデルの名前です。このカウンターの値に適用されるリセットスケジュール（毎日、毎週、毎月など）を決定します。 |
| counterName | string |  | ✓|  |  ~ 128文字 | カウンターの名前<br>回数制限モデル内でこのカウンターを一意に識別する名前です。同じ回数制限モデルを異なる名前の複数のカウンターで共有でき、個別の回数制限モデルを作成せずに別々の使用回数追跡（例：クエストごとや商品ごとに1カウンター）が可能です。 |
| userId | string |  | ✓|  |  ~ 128文字 | ユーザーID<br>`#{userId}` と設定することでログイン中のユーザーIDに置換されます。 |
| countUpValue | int |  | | 1 | 1 ~ 2147483646 | カウントアップする量 |
| maxValue | int |  | |  | 1 ~ 2147483646 | カウントアップを許容する最大値 |
| timeOffsetToken | string |  | |  |  ~ 1024文字 | タイムオフセットトークン |




**JSON**
```json
{
    "action": "Gs2Limit:CountUpByUserId",
    "request": {
        "namespaceName": "[string]ネームスペース名",
        "limitName": "[string]回数制限モデル名",
        "counterName": "[string]カウンターの名前",
        "userId": "[string]ユーザーID",
        "countUpValue": "[int]カウントアップする量",
        "maxValue": "[int]カウントアップを許容する最大値",
        "timeOffsetToken": "[string]タイムオフセットトークン"
    }
}
```

**YAML**
```yaml

action: Gs2Limit:CountUpByUserId
request:
  namespaceName: "[string]ネームスペース名"
  limitName: "[string]回数制限モデル名"
  counterName: "[string]カウンターの名前"
  userId: "[string]ユーザーID"
  countUpValue: "[int]カウントアップする量"
  maxValue: "[int]カウントアップを許容する最大値"
  timeOffsetToken: "[string]タイムオフセットトークン"
```

**GS2-Script**
```lua

transaction.service("limit").consume.count_up_by_user_id({
    namespaceName="[string]ネームスペース名",
    limitName="[string]回数制限モデル名",
    counterName="[string]カウンターの名前",
    userId="[string]ユーザーID",
    countUpValue="[int]カウントアップする量",
    maxValue="[int]カウントアップを許容する最大値",
    timeOffsetToken="[string]タイムオフセットトークン",
})
```


---

## Acquire Action

入手アクション

### Gs2Limit:CountDownByUserId

ユーザーIDを指定してカウントダウン<br>

指定されたユーザーのカウンターを指定されたカウントダウン値だけ減少させます。<br>
カウンター値は 0 を下回りません。

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

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

|  | 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128文字 | ネームスペース名<br>ネームスペース固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。 |
| limitName | string |  | ✓|  |  ~ 128文字 | 回数制限モデル名<br>このカウンターが属する回数制限モデルの名前です。このカウンターの値に適用されるリセットスケジュール（毎日、毎週、毎月など）を決定します。 |
| counterName | string |  | ✓|  |  ~ 128文字 | カウンターの名前<br>回数制限モデル内でこのカウンターを一意に識別する名前です。同じ回数制限モデルを異なる名前の複数のカウンターで共有でき、個別の回数制限モデルを作成せずに別々の使用回数追跡（例：クエストごとや商品ごとに1カウンター）が可能です。 |
| userId | string |  | ✓|  |  ~ 128文字 | ユーザーID<br>`#{userId}` と設定することでログイン中のユーザーIDに置換されます。 |
| countDownValue | int |  | | 1 | 1 ~ 2147483646 | カウントダウンする量 |
| timeOffsetToken | string |  | |  |  ~ 1024文字 | タイムオフセットトークン |




**JSON**
```json
{
    "action": "Gs2Limit:CountDownByUserId",
    "request": {
        "namespaceName": "[string]ネームスペース名",
        "limitName": "[string]回数制限モデル名",
        "counterName": "[string]カウンターの名前",
        "userId": "[string]ユーザーID",
        "countDownValue": "[int]カウントダウンする量",
        "timeOffsetToken": "[string]タイムオフセットトークン"
    }
}
```

**YAML**
```yaml

action: Gs2Limit:CountDownByUserId
request:
  namespaceName: "[string]ネームスペース名"
  limitName: "[string]回数制限モデル名"
  counterName: "[string]カウンターの名前"
  userId: "[string]ユーザーID"
  countDownValue: "[int]カウントダウンする量"
  timeOffsetToken: "[string]タイムオフセットトークン"
```

**GS2-Script**
```lua

transaction.service("limit").acquire.count_down_by_user_id({
    namespaceName="[string]ネームスペース名",
    limitName="[string]回数制限モデル名",
    counterName="[string]カウンターの名前",
    userId="[string]ユーザーID",
    countDownValue="[int]カウントダウンする量",
    timeOffsetToken="[string]タイムオフセットトークン",
})
```


---

### Gs2Limit:DeleteCounterByUserId

ユーザーIDを指定してカウンターを削除<br>

指定されたユーザーのカウンターを削除し、使用回数をリセットします。<br>
これにより、このカウンターに対する回数制限が実質的に解除され、ユーザーは再び 0 からカウントを開始できます。

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

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

|  | 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128文字 | ネームスペース名<br>ネームスペース固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。 |
| limitName | string |  | ✓|  |  ~ 128文字 | 回数制限モデル名<br>このカウンターが属する回数制限モデルの名前です。このカウンターの値に適用されるリセットスケジュール（毎日、毎週、毎月など）を決定します。 |
| userId | string |  | ✓|  |  ~ 128文字 | ユーザーID<br>`#{userId}` と設定することでログイン中のユーザーIDに置換されます。 |
| counterName | string |  | ✓|  |  ~ 128文字 | カウンターの名前<br>回数制限モデル内でこのカウンターを一意に識別する名前です。同じ回数制限モデルを異なる名前の複数のカウンターで共有でき、個別の回数制限モデルを作成せずに別々の使用回数追跡（例：クエストごとや商品ごとに1カウンター）が可能です。 |
| timeOffsetToken | string |  | |  |  ~ 1024文字 | タイムオフセットトークン |




**JSON**
```json
{
    "action": "Gs2Limit:DeleteCounterByUserId",
    "request": {
        "namespaceName": "[string]ネームスペース名",
        "limitName": "[string]回数制限モデル名",
        "userId": "[string]ユーザーID",
        "counterName": "[string]カウンターの名前",
        "timeOffsetToken": "[string]タイムオフセットトークン"
    }
}
```

**YAML**
```yaml

action: Gs2Limit:DeleteCounterByUserId
request:
  namespaceName: "[string]ネームスペース名"
  limitName: "[string]回数制限モデル名"
  userId: "[string]ユーザーID"
  counterName: "[string]カウンターの名前"
  timeOffsetToken: "[string]タイムオフセットトークン"
```

**GS2-Script**
```lua

transaction.service("limit").acquire.delete_counter_by_user_id({
    namespaceName="[string]ネームスペース名",
    limitName="[string]回数制限モデル名",
    userId="[string]ユーザーID",
    counterName="[string]カウンターの名前",
    timeOffsetToken="[string]タイムオフセットトークン",
})
```


---



