Combining Transaction Actions
Which actions may be placed in one transaction together. Background for reading the combination tables in the API reference of each service.
The microservices provided by GS2 generally have a field named transactionSettingV2 in their namespace configuration.
How the transactions issued by that namespace are executed is decided by this setting.
TransactionSettingV2 has the following structure:
| Type | Condition | Required | Default | Limitation | Description | |
|---|---|---|---|---|---|---|
| distributorNamespaceId | string | ✓ | “grn:gs2:{region}:{ownerId}:distributor:default” | ~ 1024 characters | The GS2-Distributor namespace used to execute transactions | |
| enableParallelExecution | bool | ✓ | false | Whether to execute the actions in parallel instead of sequentially |
These two fields are all there is to set. Everything else about how a transaction runs is fixed to the recommended configuration, so whichever you choose, the following three things always hold:
These three also apply to the pre-script of the API that issued the transaction. For example, if you have a script configured for product purchases, the data that script rewrote by calling the GS2 API, and any transaction the script itself issued, are applied together when the product purchase API succeeds.
The GS2-Distributor namespace used to execute the transaction.
Unless you want to separate transaction execution per purpose, the default namespace prepared with the project is enough.
Decides whether the actions in a transaction run one at a time or all at once. In practice this is the only field you actually choose.
false)Each action works on top of what the actions before it wrote. The actions run in verify, consume, acquire order, one at a time, and this is what lets you:
%{Gs2Xxx:ActionName.path[0].field} to feed the result of an earlier verify or consume action into the parameters of a later verify, consume or acquire actionOnly the results of verify and consume actions can be referenced with %{...}; the result of an acquire action cannot.
When the same action name appears more than once, the first one to run wins.
A placeholder that cannot be resolved is left as-is in the parameter, which can fail validation if the parameter is a numeric field.
The cost is:
The order within each phase is decided by the action name and then by the target resource. It is not the order the actions were written in, so you cannot choose the execution order by rearranging them. Consume actions always run before acquire actions, whatever their names.
true)The actions run in parallel against a single snapshot of the data. The response time is that of the slowest single action, and there is no limit on the number of actions.
The cost is:
database:transaction:same.resource (400).%{...} may reference only the results of an earlier phase (verify, then consume, then acquire). A reference to an action in the same phase is left unresolved, and a phase that contains %{...} waits for the earlier phases to complete, which lengthens the response time by that amount.Enable this only when you can guarantee that no two actions in the same transaction write the same data.
This setting does not change what happens when the transaction is issued. Actions against the same resource are still folded into one, still dropped, or still rejected with an error at that point, under sequential and parallel execution alike. What changes is only what happens once the actions reach execution. For which actions may be specified together in one transaction, see Combining transaction actions.
graph TD
Start["Configure transactionSettingV2"] --> Q3{"Can you guarantee that no two<br/>actions write the same data?"}
Q3 -- Cannot guarantee --> Sequential["enableParallelExecution = false (default)"]
Q3 -- Can guarantee --> Q4{"Does a later action reference<br/>the result of an earlier action?"}
Q4 -- References one in the same phase --> Sequential
Q4 -- No reference, or references<br/>only an earlier phase --> Q1{"21 or more actions, or<br/>response time to cut down?"}
Q1 -- Neither --> Sequential
Q1 -- Either --> Parallel["enableParallelExecution = true"]When in doubt, leave it at the default sequential execution. Sequential execution places the fewest constraints on how a transaction may be built, and most of the combinations that fail under parallel execution succeed under it.
Note that sequential execution cannot issue 21 or more actions, so if you exceed the limit and also cannot avoid writing the same data, split the transaction.
Before TransactionSettingV2 existed, how a transaction was executed was specified with the transactionSetting field of the namespace configuration.
transactionSetting is obsolete. It is kept for namespaces created before TransactionSettingV2 existed, and it applies only while TransactionSettingV2 is unset.
Do not use it on a newly created namespace.
transactionSetting exposes each part of transaction execution as a separate field – AutoRun, AtomicCommit, asynchronous execution using GS2-Distributor, batch application of script results, asynchronous processing of acquire actions via GS2-JobQueue, and sequential execution – so combinations other than the recommended one can be built.
TransactionSettingV2 is that recommended combination expressed as a single setting.
Setting TransactionSettingV2 fixes the fields of transactionSetting as follows:
transactionSetting field | Value under TransactionSettingV2 |
|---|---|
| enableAutoRun | true |
| enableAtomicCommit | true |
| enableSequentialExecution | the negation of enableParallelExecution |
| transactionUseDistributor | false |
| commitScriptResultInUseDistributor | false |
| acquireActionUseJobQueue | false |
A namespace that uses TransactionSettingV2 therefore cannot:
Keep using transactionSetting only on a namespace that already depends on one of these behaviours.
Most of the conflicts those settings used to work around are resolved by sequential execution instead: a conflict between a pre-script’s writes and the transaction disappears because the updates made in the same request merge into a single commit, and a conflict between a consume action and an acquire action, or between two acquire actions, disappears because the same row may be updated by more than one action.
Which actions may be placed in one transaction together. Background for reading the combination tables in the API reference of each service.