Documentation index for AI agents

GS2-Lottery Transaction Actions

Specification of verify/consume/acquire transaction actions

Combining actions, and concurrency

The background common to every service is collected in Combining Transaction Actions. Read that first; the rest of this section is what GS2-Lottery adds to it.

GS2-Lottery provides two transaction actions. Each draw works out which prizes it has won and issues them as a transaction of its own, so drawing ten times means ten inner transactions. This is the thing to watch for most when using GS2-Lottery, and it is collected under “What the prizes grant” below.

What a draw touches inside GS2-Lottery depends on the kind of prize table: an ordinary table keeps no per-user state, while a box table keeps a box, identified by the combination of namespace, user, and prize table.

OperationRepeated in one transactionAcross a nested transactionBoundary that separates targets
Drawing
DrawByUserId
Combined where the lottery model and the config match, and the draw counts are added up. Draws with differing configs against one box failFails for a box table; no collision for an ordinary tablenamespace, user, lottery model, config
Resetting a box
ResetBoxByUserId
Combined into oneFailsnamespace, user, prize table

An ordinary prize table keeps no per-user state, so drawing from it any number of times in one transaction never collides here. What the draws hand out is another matter, covered below.

Drawing and resetting are separate rows, and against one box they share a boundary, so they cannot go in one transaction. Resetting a box and then drawing from it does not work in one transaction either, quite apart from the collision: a draw works from the state at the start of the transaction and cannot see the reset.

What the prizes grant

The prizes of each draw are issued as an inner transaction of their own, so the restrictions of whichever services they belong to apply, and so does “Take care with nested transactions” below. Two draws mean two inner transactions, and those are not combined with each other either.

This is what needs the most care in GS2-Lottery. Drawing ten times, or drawing several times in one transaction, easily produces two prizes that grant the same item, the same currency, or the same status. Whether that is allowed is decided not by GS2-Lottery but by the services those prizes belong to. Read their pages on nested transactions.

A prize that has reached its own draw limit is not won; another prize is drawn instead. Reaching the limit does not make the transaction fail.

Take care with nested transactions

A box drawn from the inside collides with the same box reset from the outside, and the transaction fails.

If you want to avoid these restrictions

Drawing and resetting a box are both acquire actions, so turning acquireActionUseJobQueue on clears both “a draw from a box together with a reset of it” and “several draws with differing configs”. Turning enableAtomicCommit off additionally stops the prizes of separate draws from gathering into one write.

Concurrency and retries

Drawing from an ordinary prize table does not conflict with a concurrent request inside GS2-Lottery itself. Whether it conflicts is decided by what the prizes grant.

Drawing from a box and resetting a box both rewrite the box, so running them at the same time makes the one confirmed later return a conflict (409). This is what stops the same prize being taken out of a box twice. Retrying re-evaluates against the latest state of the box.


Acquire Action

Gs2Lottery:DrawByUserId

Execute a lottery by specifying a User ID

Performs a lottery draw for the specified user based on the lottery model configuration. The lottery supports two methods: Prize Table mode (using predefined probability tables) and Script mode (using a GS2-Script to determine prizes). In box lottery mode, drawn prizes are removed from the box and cannot be drawn again. If the box is empty, an Empty error is returned. The drawn prizes are issued as a transaction.

Quantity specification supported: YES

Reversible action: NO

TypeConditionRequiredDefaultValue LimitsDescription
namespaceNamestring
~ 128 charsNamespace name
lotteryNamestring
~ 128 charsLottery Model name
Unique Lottery Model name. Specified using alphanumeric characters, hyphen (-), underscore (_), and period (.).
userIdstring
~ 128 charsUser ID
Specify #{userId} to substitute the currently logged-in user’s ID.
countint
1 ~ 1000Number of draws
configList<Config>[]0 ~ 1000 itemsConfiguration values applied to transaction placeholders
timeOffsetTokenstring~ 1024 charsTime offset token
{
    "action": "Gs2Lottery:DrawByUserId",
    "request": {
        "namespaceName": "[string]Namespace name",
        "lotteryName": "[string]Lottery Model name",
        "userId": "[string]User ID",
        "count": "[int]Number of draws",
        "config": [
            {
                "key": "[string]Name",
                "value": "[string]Value"
            }
        ],
        "timeOffsetToken": "[string]Time offset token"
    }
}
action: Gs2Lottery:DrawByUserId
request:
  namespaceName: "[string]Namespace name"
  lotteryName: "[string]Lottery Model name"
  userId: "[string]User ID"
  count: "[int]Number of draws"
  config: 
    - key: "[string]Name"
      value: "[string]Value"
  timeOffsetToken: "[string]Time offset token"
transaction.service("lottery").acquire.draw_by_user_id({
    namespaceName="[string]Namespace name",
    lotteryName="[string]Lottery Model name",
    userId="[string]User ID",
    count="[int]Number of draws",
    config={
        {
            key="[string]Name",
            value="[string]Value"
        }
    },
    timeOffsetToken="[string]Time offset token",
})

Gs2Lottery:ResetBoxByUserId

Reset box with specified user ID

Resets the specified user’s box to its initial state, returning all drawn prizes back into the box.

Quantity specification supported: NO

Reversible action: NO

TypeConditionRequiredDefaultValue LimitsDescription
namespaceNamestring
~ 128 charsNamespace name
Unique Namespace name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
prizeTableNamestring
~ 128 charsPrize Table name
userIdstring
~ 128 charsUser ID
Specify #{userId} to substitute the currently logged-in user’s ID.
timeOffsetTokenstring~ 1024 charsTime offset token
{
    "action": "Gs2Lottery:ResetBoxByUserId",
    "request": {
        "namespaceName": "[string]Namespace name",
        "prizeTableName": "[string]Prize Table name",
        "userId": "[string]User ID",
        "timeOffsetToken": "[string]Time offset token"
    }
}
action: Gs2Lottery:ResetBoxByUserId
request:
  namespaceName: "[string]Namespace name"
  prizeTableName: "[string]Prize Table name"
  userId: "[string]User ID"
  timeOffsetToken: "[string]Time offset token"
transaction.service("lottery").acquire.reset_box_by_user_id({
    namespaceName="[string]Namespace name",
    prizeTableName="[string]Prize Table name",
    userId="[string]User ID",
    timeOffsetToken="[string]Time offset token",
})