GS2-Enhance 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-Enhance adds to it.
The transaction actions of GS2-Enhance fall into two groups: those that go through a progress, and those that do not. A progress is identified by the combination of namespace and user, and there is only one per user.
| Operation | Repeated in one transaction | Across a nested transaction | Boundary that separates targets | Under sequential execution mode |
|---|---|---|---|---|
Creating a progressCreateProgressByUserId | Combined into one | Fails | namespace, user | Still fails against another creation: the second one now sees the first one’s progress through the same read that already guards against a real duplicate, and reports it as already existing. Setting force on the second one does not help — the check is then skipped, but the two writes to the same row cannot be combined and the transaction fails (400). Still fails against a discard as well, see below |
Discarding a progressDeleteProgressByUserId | Combined into one | Fails | namespace, user | Still fails. The two are no longer gathered into one, so the second discard runs against a progress that is already gone and is rejected as not found (404) |
Enhancing and unleashing directlyDirectEnhanceByUserId UnleashByUserId | Combined into one where the rate, the target, and every material match; differ in any of them and each runs | Does not touch the progress | namespace, user, rate, target item, materials | No change; it still does not touch the progress |
Creating and discarding are separate rows sharing a boundary, so they cannot go in one transaction.
Creating a progress fails where another progress already exists. This is what keeps a player to one enhancement at a time. The check is made against the state at the start of the transaction, so quite apart from the collision, a transaction cannot discard a progress and then create a new one. Turning on sequential execution mode (enableSequentialExecution or TransactionSettingV2) does not make this work. Discarding is a consume action and always runs before creating, which is an acquire action, so the creation’s existence check does pass — but the discard and the creation are then two writes to the same row that cannot be combined, and the transaction fails (400) at the point they are put together. Discarding a progress and creating a new one still takes two transactions. It does not change what happens when two creations are placed together either — see the table above.
DirectEnhanceByUserId and UnleashByUserId do not touch the progress at all. They work out which materials to consume and which result to grant, and issue those as a transaction of their own. Two of them with different materials are separate targets and both run, but what they consume and grant gathers into the same transaction.
Materials are usually consumed from GS2-Inventory and results acquired there too, so where the outer transaction touches the same item, read the GS2-Inventory page as well.
Take care with nested transactions
A progress created from the inside collides with a progress discarded from the outside, and the transaction fails. Turning on sequential execution mode removes this failure: discarding is a consume action and always runs before the acquire action that triggers the inner creation, so the discard has already happened by the time the inner creation’s existence check runs, and it finds no progress in the way.
If you want to avoid these restrictions
Creating a progress, enhancing, and unleashing are acquire actions; discarding a progress is a consume action. Turning acquireActionUseJobQueue on clears collisions between two creations. Turning enableAtomicCommit off clears a creation together with a discard, and because consume actions then run before acquire actions, discarding and creating a new progress in one transaction starts to work as well.
Concurrency and retries
Where several requests create or discard the same user’s progress at the same time, the one confirmed later returns a conflict (409). Retrying re-evaluates against the latest state, so it succeeds if the progress is in the expected state and returns an error if another enhancement has already started.
Direct enhancing and unleashing do not touch the progress, so how much they conflict depends entirely on the services their materials and results belong to.
Consume Action
Gs2Enhance:DeleteProgressByUserId
Delete running enhancement by User ID
Deletes the progress record of the enhancement currently in progress for the specified user. This cancels the ongoing 2-phase enhancement, discarding the pre-calculated experience and bonus rate. Materials that were already consumed during the Start phase are not automatically refunded.
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 (.). | ||
| 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": "Gs2Enhance:DeleteProgressByUserId",
"request": {
"namespaceName": "[string]Namespace name",
"userId": "[string]User ID",
"timeOffsetToken": "[string]Time offset token"
}
}action: Gs2Enhance:DeleteProgressByUserId
request:
namespaceName: "[string]Namespace name"
userId: "[string]User ID"
timeOffsetToken: "[string]Time offset token"transaction.service("enhance").consume.delete_progress_by_user_id({
namespaceName="[string]Namespace name",
userId="[string]User ID",
timeOffsetToken="[string]Time offset token",
})Acquire Action
Gs2Enhance:DirectEnhanceByUserId
Perform enhancement by User ID
Consumes the specified materials to grant experience to the target item set based on the Enhancement Rate Model. The experience gained is calculated from the materials according to the experience hierarchy defined in the rate model, and a bonus rate is drawn from the configured bonus rate probability table. The result includes the acquired experience amount and the bonus rate applied. A transaction (transaction) is issued to execute the material consumption and experience acquisition.
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 (.). | ||
| rateName | string | ✓ | ~ 128 chars | Enhancement Rate Model name Unique Enhancement Rate Model 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. | ||
| targetItemSetId | string | ✓ | ~ 1024 chars | GRN of the Item Set to be enhanced | ||
| materials | List<Material> | ✓ | 1 ~ 10 items | List of Material | ||
| config | List<Config> | [] | 0 ~ 32 items | Configuration values applied to transaction variables | ||
| timeOffsetToken | string | ~ 1024 chars | Time offset token |
{
"action": "Gs2Enhance:DirectEnhanceByUserId",
"request": {
"namespaceName": "[string]Namespace name",
"rateName": "[string]Enhancement Rate Model name",
"userId": "[string]User ID",
"targetItemSetId": "[string]GRN of the Item Set to be enhanced",
"materials": [
{
"materialItemSetId": "[string]GRN of Item Set that will be used as materials for enhancement",
"count": "[int]Number of consumption"
}
],
"config": [
{
"key": "[string]Name",
"value": "[string]Value"
}
],
"timeOffsetToken": "[string]Time offset token"
}
}action: Gs2Enhance:DirectEnhanceByUserId
request:
namespaceName: "[string]Namespace name"
rateName: "[string]Enhancement Rate Model name"
userId: "[string]User ID"
targetItemSetId: "[string]GRN of the Item Set to be enhanced"
materials:
- materialItemSetId: "[string]GRN of Item Set that will be used as materials for enhancement"
count: "[int]Number of consumption"
config:
- key: "[string]Name"
value: "[string]Value"
timeOffsetToken: "[string]Time offset token"transaction.service("enhance").acquire.direct_enhance_by_user_id({
namespaceName="[string]Namespace name",
rateName="[string]Enhancement Rate Model name",
userId="[string]User ID",
targetItemSetId="[string]GRN of the Item Set to be enhanced",
materials={
{
materialItemSetId="[string]GRN of Item Set that will be used as materials for enhancement",
count="[int]Number of consumption"
}
},
config={
{
key="[string]Name",
value="[string]Value"
}
},
timeOffsetToken="[string]Time offset token",
})Gs2Enhance:UnleashByUserId
Perform unleash by User ID
Used for enhancement processing to raise the grade of the resource managed by GS2-Grade. In particular, it is used for the type of unleash that raises the level cap by consuming the same type of item as a material.
Instead of consuming the specified material, the grade of the resource to be unleashed can be increased by 1. Even if the material resource has a resource such as experience value, the resource will not be inherited. If inheritance is required, the resource must be converted to a resource for inheritance in advance.
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 (.). | ||
| rateName | string | ✓ | ~ 128 chars | Enhancement Rate Model name Unique Enhancement Rate Model 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. | ||
| targetItemSetId | string | ✓ | ~ 1024 chars | GRN for the Item Set subject to limit break | ||
| materials | List<string> | ✓ | 1 ~ 1000 items | List of materials that break the limit | ||
| config | List<Config> | [] | 0 ~ 32 items | Configuration values applied to transaction variables | ||
| timeOffsetToken | string | ~ 1024 chars | Time offset token |
{
"action": "Gs2Enhance:UnleashByUserId",
"request": {
"namespaceName": "[string]Namespace name",
"rateName": "[string]Enhancement Rate Model name",
"userId": "[string]User ID",
"targetItemSetId": "[string]GRN for the Item Set subject to limit break",
"materials": [
"[string]Material"
],
"config": [
{
"key": "[string]Name",
"value": "[string]Value"
}
],
"timeOffsetToken": "[string]Time offset token"
}
}action: Gs2Enhance:UnleashByUserId
request:
namespaceName: "[string]Namespace name"
rateName: "[string]Enhancement Rate Model name"
userId: "[string]User ID"
targetItemSetId: "[string]GRN for the Item Set subject to limit break"
materials:
- "[string]Material"
config:
- key: "[string]Name"
value: "[string]Value"
timeOffsetToken: "[string]Time offset token"transaction.service("enhance").acquire.unleash_by_user_id({
namespaceName="[string]Namespace name",
rateName="[string]Enhancement Rate Model name",
userId="[string]User ID",
targetItemSetId="[string]GRN for the Item Set subject to limit break",
materials={
"[string]Material"
},
config={
{
key="[string]Name",
value="[string]Value"
}
},
timeOffsetToken="[string]Time offset token",
})Gs2Enhance:CreateProgressByUserId
Start enhancement by User ID
Creates a progress record for a 2-phase enhancement flow. Validates the target item set and materials against the rate model, calculates the experience to be gained from the materials, and draws a bonus rate from the probability table. The calculated experience and bonus rate are stored in the progress record for later use when the enhancement is completed via the End API. If force is true, any existing progress for the user will be discarded and replaced.
Quantity specification supported: NO
Reversible action: YES
| 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. | ||
| rateName | string | ✓ | ~ 128 chars | Enhancement Rate Model name The name of the Enhancement Rate Model that defines the parameters for this enhancement operation. References the model that specifies the target inventory, material inventory, experience hierarchy, and bonus rates. | ||
| targetItemSetId | string | ✓ | ~ 1024 chars | GRN of the Item Set to be enhanced | ||
| materials | List<Material> | 0 ~ 10 items | List of materials | |||
| force | bool | false | If there is an enhancement that has already been started, it can be discarded and started, or | |||
| timeOffsetToken | string | ~ 1024 chars | Time offset token |
{
"action": "Gs2Enhance:CreateProgressByUserId",
"request": {
"namespaceName": "[string]Namespace name",
"userId": "[string]User ID",
"rateName": "[string]Enhancement Rate Model name",
"targetItemSetId": "[string]GRN of the Item Set to be enhanced",
"materials": [
{
"materialItemSetId": "[string]GRN of Item Set that will be used as materials for enhancement",
"count": "[int]Number of consumption"
}
],
"force": "[bool]If there is an enhancement that has already been started, it can be discarded and started, or",
"timeOffsetToken": "[string]Time offset token"
}
}action: Gs2Enhance:CreateProgressByUserId
request:
namespaceName: "[string]Namespace name"
userId: "[string]User ID"
rateName: "[string]Enhancement Rate Model name"
targetItemSetId: "[string]GRN of the Item Set to be enhanced"
materials:
- materialItemSetId: "[string]GRN of Item Set that will be used as materials for enhancement"
count: "[int]Number of consumption"
force: "[bool]If there is an enhancement that has already been started, it can be discarded and started, or"
timeOffsetToken: "[string]Time offset token"transaction.service("enhance").acquire.create_progress_by_user_id({
namespaceName="[string]Namespace name",
userId="[string]User ID",
rateName="[string]Enhancement Rate Model name",
targetItemSetId="[string]GRN of the Item Set to be enhanced",
materials={
{
materialItemSetId="[string]GRN of Item Set that will be used as materials for enhancement",
count="[int]Number of consumption"
}
},
force="[bool]If there is an enhancement that has already been started, it can be discarded and started, or",
timeOffsetToken="[string]Time offset token",
})