GS2-Lottery 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.
| Operation | Repeated in one transaction | Across a nested transaction | Boundary that separates targets |
|---|---|---|---|
DrawingDrawByUserId | Combined where the lottery model and the config match, and the draw counts are added up. Draws with differing configs against one box fail | Fails for a box table; no collision for an ordinary table | namespace, user, lottery model, config |
Resetting a boxResetBoxByUserId | Combined into one | Fails | namespace, 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
| Type | Condition | Required | Default | Value Limits | Description | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128 chars | Namespace name | ||
| lotteryName | string | ✓ | ~ 128 chars | Lottery Model name Unique Lottery Model name. Specified using alphanumeric characters, hyphen (-), underscore (_), and period (.). | ||
| userId | string | ✓ | ~ 128 chars | User ID Specify #{userId} to substitute the currently logged-in user’s ID. | ||
| count | int | ✓ | 1 ~ 1000 | Number of draws | ||
| config | List<Config> | [] | 0 ~ 1000 items | Configuration values applied to transaction placeholders | ||
| timeOffsetToken | string | ~ 1024 chars | 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"
}
}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
| Type | Condition | Required | Default | Value Limits | Description | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128 chars | Namespace name Unique Namespace name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.). | ||
| prizeTableName | string | ✓ | ~ 128 chars | Prize Table name | ||
| userId | string | ✓ | ~ 128 chars | User ID Specify #{userId} to substitute the currently logged-in user’s ID. | ||
| timeOffsetToken | string | ~ 1024 chars | 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"
}
}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",
})