GS2-Distributor 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-Distributor adds to it.
The transaction actions of GS2-Distributor handle logic rather than data. They hold other actions inside them and decide whether to run those. GS2-Distributor keeps no state of its own, so these actions never collide because of GS2-Distributor.
| Operation | Repeated in one transaction | Across a nested transaction | Boundary that separates targets |
|---|---|---|---|
Evaluating an and expressionAndExpressionByUserId | Each is evaluated independently | No collision; it only reads | every expression is its own target |
Evaluating an or expressionOrExpressionByUserId | Each is evaluated independently | No collision; it only reads | every expression is its own target |
Evaluating an if expressionIfExpressionByUserId | Each is evaluated independently | Depends on what the taken branch writes | every expression is its own target |
The and and or expressions hold verify actions inside, which only read. An if expression holds consume actions in its two branches, and those do write.
Actions inside one expression are combined as usual: two identical actions against the same target inside one and expression become one. They are never combined with the actions of the outer transaction, nor with the actions inside another expression.
That is the thing to watch for. Where a branch of an if consumes the same currency, or rewrites the same dictionary, as an action written directly on the transaction, the two writes arrive separately and run straight into the restrictions of that service.
Everything is evaluated against the state at the start of the transaction
Like any verify action, an expression reads the state at the start of the transaction. It cannot see what the same transaction changed, including what another expression in it changed. Two if expressions whose conditions depend on each other therefore cannot be chained: both are evaluated against the same starting state.
Take care with nested transactions
The writes of an inner transaction fall outside the actions specified directly on the outer one, so a branch that grants an item which the outer transaction also grants will make the transaction fail where that item does not allow two writes.
Read the branches of an expression as part of the transaction too.
If you want to avoid these restrictions
Turning enableAtomicCommit off stops a branch and the outer actions from gathering into one write. acquireActionUseJobQueue separates only the acquire actions around the expression: the branches of an if hold consume actions, so the branches themselves are not separated.
Concurrency and retries
GS2-Distributor itself never returns a conflict. Whether an expression conflicts with a concurrent request is decided by what the inner actions write, and the retry guidance of those services applies.
An expression can also simply fail because its condition did not hold. That is a result, not an error to retry.
Verify Action
Gs2Distributor:IfExpressionByUserId
Validate the condition and switch the contents of the Consume Action
Evaluates a verify action as a condition, and executes either the trueActions or falseActions list of consume actions based on the result. This enables conditional branching within a transaction, allowing different consume actions to be executed depending on the verification outcome. When multiplyValueSpecifyingQuantity is enabled, the values used for verification are also multiplied by the specified quantity.
Quantity specification supported: 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 (.). | ||
| userId | string | ✓ | ~ 128 chars | User ID Specify #{userId} to substitute the currently logged-in user’s ID. | ||
| condition | VerifyAction | ✓ | Condition | |||
| trueActions | List<ConsumeAction> | 0 ~ 10 items | List of Consume Actions to be executed when the condition is true | |||
| falseActions | List<ConsumeAction> | 0 ~ 10 items | List of Consume Actions to be executed when the condition is false | |||
| multiplyValueSpecifyingQuantity | bool | true | Whether to multiply the value used for verification when specifying the quantity | |||
| timeOffsetToken | string | ~ 1024 chars | Time offset token |
{
"action": "Gs2Distributor:IfExpressionByUserId",
"request": {
"namespaceName": "[string]Namespace name",
"userId": "[string]User ID",
"condition": {
"action": "[string]Type of Verify Action",
"request": "[string]JSON string of the request used when executing the action"
},
"trueActions": [
{
"action": "[string]Type of Consume Action",
"request": "[string]JSON string of the request used when executing the action"
}
],
"falseActions": [
{
"action": "[string]Type of Consume Action",
"request": "[string]JSON string of the request used when executing the action"
}
],
"multiplyValueSpecifyingQuantity": "[bool]Whether to multiply the value used for verification when specifying the quantity",
"timeOffsetToken": "[string]Time offset token"
}
}action: Gs2Distributor:IfExpressionByUserId
request:
namespaceName: "[string]Namespace name"
userId: "[string]User ID"
condition:
action: "[string]Type of Verify Action"
request: "[string]JSON string of the request used when executing the action"
trueActions:
- action: "[string]Type of Consume Action"
request: "[string]JSON string of the request used when executing the action"
falseActions:
- action: "[string]Type of Consume Action"
request: "[string]JSON string of the request used when executing the action"
multiplyValueSpecifyingQuantity: "[bool]Whether to multiply the value used for verification when specifying the quantity"
timeOffsetToken: "[string]Time offset token"transaction.service("distributor").verify.if_expression_by_user_id({
namespaceName="[string]Namespace name",
userId="[string]User ID",
condition={
action="[string]Type of Verify Action",
request="[string]JSON string of the request used when executing the action"
},
trueActions={
{
action="[string]Type of Consume Action",
request="[string]JSON string of the request used when executing the action"
}
},
falseActions={
{
action="[string]Type of Consume Action",
request="[string]JSON string of the request used when executing the action"
}
},
multiplyValueSpecifyingQuantity="[bool]Whether to multiply the value used for verification when specifying the quantity",
timeOffsetToken="[string]Time offset token",
})Gs2Distributor:AndExpressionByUserId
Perform multiple verification actions and determine if all are true
Executes multiple verify actions and succeeds only if all of them evaluate to true (AND logic). If any verify action fails, the entire expression fails. This is useful for combining multiple preconditions that must all be satisfied before proceeding with a transaction.
Quantity specification supported: 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 (.). | ||
| userId | string | ✓ | ~ 128 chars | User ID Specify #{userId} to substitute the currently logged-in user’s ID. | ||
| actions | List<VerifyAction> | 0 ~ 10 items | List of Verify Actions | |||
| timeOffsetToken | string | ~ 1024 chars | Time offset token |
{
"action": "Gs2Distributor:AndExpressionByUserId",
"request": {
"namespaceName": "[string]Namespace name",
"userId": "[string]User ID",
"actions": [
{
"action": "[string]Type of Verify Action",
"request": "[string]JSON string of the request used when executing the action"
}
],
"timeOffsetToken": "[string]Time offset token"
}
}action: Gs2Distributor:AndExpressionByUserId
request:
namespaceName: "[string]Namespace name"
userId: "[string]User ID"
actions:
- action: "[string]Type of Verify Action"
request: "[string]JSON string of the request used when executing the action"
timeOffsetToken: "[string]Time offset token"transaction.service("distributor").verify.and_expression_by_user_id({
namespaceName="[string]Namespace name",
userId="[string]User ID",
actions={
{
action="[string]Type of Verify Action",
request="[string]JSON string of the request used when executing the action"
}
},
timeOffsetToken="[string]Time offset token",
})Gs2Distributor:OrExpressionByUserId
Perform multiple verification actions and determine if any are true
Executes multiple verify actions and succeeds if at least one of them evaluates to true (OR logic). The expression fails only if all verify actions fail. This is useful for defining alternative conditions where satisfying any one of them is sufficient to proceed.
Quantity specification supported: 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 (.). | ||
| userId | string | ✓ | ~ 128 chars | User ID Specify #{userId} to substitute the currently logged-in user’s ID. | ||
| actions | List<VerifyAction> | 0 ~ 10 items | List of Verify Actions | |||
| timeOffsetToken | string | ~ 1024 chars | Time offset token |
{
"action": "Gs2Distributor:OrExpressionByUserId",
"request": {
"namespaceName": "[string]Namespace name",
"userId": "[string]User ID",
"actions": [
{
"action": "[string]Type of Verify Action",
"request": "[string]JSON string of the request used when executing the action"
}
],
"timeOffsetToken": "[string]Time offset token"
}
}action: Gs2Distributor:OrExpressionByUserId
request:
namespaceName: "[string]Namespace name"
userId: "[string]User ID"
actions:
- action: "[string]Type of Verify Action"
request: "[string]JSON string of the request used when executing the action"
timeOffsetToken: "[string]Time offset token"transaction.service("distributor").verify.or_expression_by_user_id({
namespaceName="[string]Namespace name",
userId="[string]User ID",
actions={
{
action="[string]Type of Verify Action",
request="[string]JSON string of the request used when executing the action"
}
},
timeOffsetToken="[string]Time offset token",
})