Documentation index for AI agents

GS2-AdReward 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-AdReward adds to it.

The transaction actions of GS2-AdReward address the single point balance that exists per namespace and per user.

OperationRepeated in one transactionAcross a nested transactionBoundary that separates targets
Acquiring points
AcquirePointByUserId
Combined, and the points are added upAdded upnamespace, user
Consuming points
ConsumePointByUserId
Combined, and the balance is checked against the totalAdded up, except that a total consumption beyond the balance returns a conflict (409) that a retry cannot clear while the balance stays shortnamespace, user

Both rows are written as a pure increment on the same balance, so an acquire and a consume may be placed together and each is applied. Acquiring 100 and acquiring 50 is handled as one acquire of 150. Against a balance of 100, consuming 60 and consuming 30 leaves 10; consuming 60 and acquiring 200 leaves 240.

Where the total consumption exceeds the balance at the start of the transaction, an insufficient points error (400) is returned and no part of the consumption is applied.

Points acquired in a transaction cannot pay for a consume action in that same transaction. Consume actions always run before acquire actions, so only the balance at the start of the transaction is available. Split the transaction where you need that.

Take care with nested transactions

GS2-AdReward tolerates this. Increases and decreases arriving from separate transactions are still applied together as one update to the balance, so they do not conflict. The only exception is when the consumption arriving through these separate routes adds up to more than the balance: the transaction is then rejected as a conflict (409) rather than as an insufficient points error (400), and the balance is left unchanged. Retrying does not help unless the balance has grown in the meantime.

If you want to avoid these restrictions

The one restriction above comes from the order of execution. Neither enableAtomicCommit nor acquireActionUseJobQueue changes that order, so neither of them lifts it. Split the transaction if you want acquired points to be spent.

Concurrency and retries

Concurrent acquires, and an acquire running concurrently with a consume, do not conflict in principle, because each increase and decrease is applied reliably.

When updates to the same point balance are concentrated in a short period, a transient conflict (409) may be returned. The balance is not the cause, so retrying after a short interval will succeed.

When consume actions in separate transactions run concurrently and their total exceeds the balance, a conflict (409) may be returned. A retry re-evaluates the request against the latest balance, so it succeeds if the balance is sufficient at that point, and returns an insufficient points error (400) if it is not.


Consume Action

Gs2AdReward:ConsumePointByUserId

Consume Point by User ID

Consumes points from the specified user ID and returns the updated point information. An error is returned if the user does not have enough points to cover the requested consumption amount. If a GS2-Script is configured in the Namespace’s consume script settings, the script is executed before consuming points, allowing custom validation or modification of the consumed amount. After the point deduction, a change notification is sent if configured in the Namespace settings.

Quantity specification supported: YES

Reversible action: YES

TypeConditionRequiredDefaultValue LimitsDescription
namespaceNamestring
~ 128 charsNamespace name
Unique Namespace name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
userIdstring
~ 128 charsUser ID
Specify #{userId} to substitute the currently logged-in user’s ID.
pointlong
1 ~ 9223372036854775805Consume Points
timeOffsetTokenstring~ 1024 charsTime offset token
{
    "action": "Gs2AdReward:ConsumePointByUserId",
    "request": {
        "namespaceName": "[string]Namespace name",
        "userId": "[string]User ID",
        "point": "[long]Consume Points",
        "timeOffsetToken": "[string]Time offset token"
    }
}
action: Gs2AdReward:ConsumePointByUserId
request:
  namespaceName: "[string]Namespace name"
  userId: "[string]User ID"
  point: "[long]Consume Points"
  timeOffsetToken: "[string]Time offset token"
transaction.service("adReward").consume.consume_point_by_user_id({
    namespaceName="[string]Namespace name",
    userId="[string]User ID",
    point="[long]Consume Points",
    timeOffsetToken="[string]Time offset token",
})

Acquire Action

Gs2AdReward:AcquirePointByUserId

Acquire Point by User ID

Adds a specified number of points to the specified user ID and returns the updated point information. If the user has no existing point record, a new record is automatically created before adding points. If a GS2-Script is configured in the Namespace’s acquire script settings, the script is executed before acquiring points, allowing custom validation or modification of the acquired amount. After the point addition, a change notification is sent if configured in the Namespace settings.

Quantity specification supported: YES

Reversible action: YES

TypeConditionRequiredDefaultValue LimitsDescription
namespaceNamestring
~ 128 charsNamespace name
Unique Namespace name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
userIdstring
~ 128 charsUser ID
Specify #{userId} to substitute the currently logged-in user’s ID.
pointlong
1 ~ 9223372036854775805Acquire Points
timeOffsetTokenstring~ 1024 charsTime offset token
{
    "action": "Gs2AdReward:AcquirePointByUserId",
    "request": {
        "namespaceName": "[string]Namespace name",
        "userId": "[string]User ID",
        "point": "[long]Acquire Points",
        "timeOffsetToken": "[string]Time offset token"
    }
}
action: Gs2AdReward:AcquirePointByUserId
request:
  namespaceName: "[string]Namespace name"
  userId: "[string]User ID"
  point: "[long]Acquire Points"
  timeOffsetToken: "[string]Time offset token"
transaction.service("adReward").acquire.acquire_point_by_user_id({
    namespaceName="[string]Namespace name",
    userId="[string]User ID",
    point="[long]Acquire Points",
    timeOffsetToken="[string]Time offset token",
})