Legacy review of Avoiding Transactions in Azure - #8490
Open
stevedowling wants to merge 1 commit into
Open
Conversation
PhilBastian
approved these changes
Sep 8, 2026
| ### Disadvantages | ||
|
|
||
| - There can be only a single transactional resource in the entire system. The technique can only be applied if the application fits the limitations of this transactional resource. As some Azure services throttle quite aggressively, sometimes on behavior of other tenants, capacity planning might become an issue. | ||
| - There can be only one transactional resource in the entire system. This technique can only be applied if the application fits within the limitations of this transactional resource. As some Azure services throttle quite aggressively, sometimes due to the behavior of other tenants, capacity planning might become an issue. |
Contributor
There was a problem hiding this comment.
Suggested change
| - There can be only one transactional resource in the entire system. This technique can only be applied if the application fits within the limitations of this transactional resource. As some Azure services throttle quite aggressively, sometimes due to the behavior of other tenants, capacity planning might become an issue. | |
| - The entire system is limited to only a single transactional resource and, therefore, this technique can only be applied if the application fits within the limitations of this transactional resource. Since some Azure services throttle quite aggressively, sometimes due to the behavior of other tenants, capacity planning may become an issue. |
| If a resource does not support transactions, atomic operations combined with automatic retries can be used to ensure consistency. The idea is that every atomic operation is *transactional*, meaning that the whole operation either succeeds or fails as a single unit. If all operations conform to that rule, then transactions are not needed anymore. | ||
|
|
||
| One operation that fits this criteria is a unit of work pattern with batching. With some restrictions, it can be used to emulate a transaction. Azure Storage Services allow grouping a number of operations into a single batch in order to make the whole set atomic. However, it works only for Azure Storage Tables and only when the partition key for all operations is the same. | ||
| One operation that fits this criterion is a unit of work pattern with batching. With some restrictions, it can be used to emulate a transaction. Azure Storage Services allow grouping a number of operations into a single batch in order to make the whole set atomic. However, it works only for Azure Storage Tables and only when the partition key for all operations is the same. |
Contributor
There was a problem hiding this comment.
Suggested change
| One operation that fits this criterion is a unit of work pattern with batching. With some restrictions, it can be used to emulate a transaction. Azure Storage Services allow grouping a number of operations into a single batch in order to make the whole set atomic. However, it works only for Azure Storage Tables and only when the partition key for all operations is the same. | |
| One operation that fits this criterion is a unit of work pattern with batching. With some restrictions, it can be used to emulate a transaction. Azure Storage Services allow grouping a number of operations into a single batch in order to make the whole set atomic. This only works for Azure Storage Tables however, and only when the partition key for all operations is the same. |
| @@ -45,14 +45,14 @@ Another important consideration is that regular transactions also have a *rollba | |||
| ### Disadvantages | |||
|
|
|||
| - The application must ensure that operations related to business logic are atomic, i.e. have a single insert, update or delete statement per operation. That often requires changes in program structure. | |||
Contributor
There was a problem hiding this comment.
Suggested change
| - The application must ensure that operations related to business logic are atomic, i.e. have a single insert, update or delete statement per operation. That often requires changes in program structure. | |
| - The application must ensure that operations related to business logic are atomic; i.e. have a single insert, update or delete statement per operation. That often requires changes in program structure. |
|
|
||
| ## Sagas and compensation logic | ||
|
|
||
| Sagas are essentially a stateful set of message handlers that can be used to track and orchestrate a transaction. The handlers communicate with each other, each of them performs a part of the transaction and then notifies whether it succeeded or failed. Depending on the partial results, the saga decides what needs to happen to the rest of the transaction; whether to continue the transaction or to roll it back. The latter is often referred to as *compensation*, as it tries to compensate for the failure at a business logic level. |
Contributor
There was a problem hiding this comment.
Suggested change
| Sagas are essentially a stateful set of message handlers that can be used to track and orchestrate a transaction. The handlers communicate with each other, each of them performs a part of the transaction and then notifies whether it succeeded or failed. Depending on the partial results, the saga decides what needs to happen to the rest of the transaction; whether to continue the transaction or to roll it back. The latter is often referred to as *compensation*, as it tries to compensate for the failure at a business logic level. | |
| Sagas are essentially a stateful set of message handlers that can be used to track and orchestrate a transaction. The handlers communicate with each other; each of them performs a part of the transaction and then notifies whether it succeeded or failed. Depending on the partial results, the saga decides what needs to happen to the rest of the transaction; whether to continue the transaction or to roll it back. The latter is often referred to as *compensation*, as it tries to compensate for the failure at a business logic level. |
| Sagas are essentially a stateful set of message handlers that can be used to track and orchestrate a transaction. The handlers communicate with each other, each of them performs a part of the transaction and then notifies whether it succeeded or failed. Depending on the partial results, the saga decides what needs to happen to the rest of the transaction; whether to continue the transaction or to roll it back. The latter is often referred to as *compensation*, as it tries to compensate for the failure at a business logic level. | ||
|
|
||
| In essence, using sagas is implementing a Distributed Transaction Coordinator that operates on business logic level instead of using a two-phase commit protocol. | ||
| In essence, sagas implement a Distributed Transaction Coordinator that operates at a business logic level instead of using a two-phase commit protocol. |
Contributor
There was a problem hiding this comment.
Suggested change
| In essence, sagas implement a Distributed Transaction Coordinator that operates at a business logic level instead of using a two-phase commit protocol. | |
| In essence, sagas implement a Distributed Transaction Coordinator that operate at a business logic level instead of using a two-phase commit protocol. |
| ### Entities and messages with version information | ||
|
|
||
| Idempotency can be achieved by adding versioning information to the entities. Typically it is in the form of a timestamp or a version number. | ||
| Idempotency can be achieved by adding versioning information to the entities. Typically, it is in the form of a timestamp or a version number. |
Contributor
There was a problem hiding this comment.
this one doesn't sound right to me
Suggested change
| Idempotency can be achieved by adding versioning information to the entities. Typically, it is in the form of a timestamp or a version number. | |
| Idempotency can be achieved by adding versioning information to the entities. Typically it is in the form of a timestamp or a version number. |
| ### Side effect checks | ||
|
|
||
| In some situations, it is possible to verify if a command has been executed by checking its indirect side effects, for example, when `TheFireIsHot` flag is set to true, then there is no need to `TurnOnTheFire`. | ||
| In some situations, it is possible to verify if a command has been executed by checking its indirect side effects, for example, when the `TheFireIsHot` flag is set to true, there is no need to `TurnOnTheFire`. |
Contributor
There was a problem hiding this comment.
Suggested change
| In some situations, it is possible to verify if a command has been executed by checking its indirect side effects, for example, when the `TheFireIsHot` flag is set to true, there is no need to `TurnOnTheFire`. | |
| In some situations, it is possible to verify if a command has been executed by checking its indirect side effects, e.g. when the `TheFireIsHot` flag is set to true, there is no need to `TurnOnTheFire`. |
| In some situations, it is possible to verify if a command has been executed by checking its indirect side effects, for example, when `TheFireIsHot` flag is set to true, then there is no need to `TurnOnTheFire`. | ||
| In some situations, it is possible to verify if a command has been executed by checking its indirect side effects, for example, when the `TheFireIsHot` flag is set to true, there is no need to `TurnOnTheFire`. | ||
|
|
||
| Arguably this is a risky approach that can lead to subtle errors. Although it's useful in the real world, it has to be used very carefully, preferably only if no other approach can be used. |
Contributor
There was a problem hiding this comment.
Suggested change
| Arguably this is a risky approach that can lead to subtle errors. Although it's useful in the real world, it has to be used very carefully, preferably only if no other approach can be used. | |
| Arguably this is a risky approach that can lead to subtle errors. Although it's useful in the real world, it has to be used very carefully; preferably only if no other approach can be used. |
| ### Accept uncertainty | ||
|
|
||
| In some systems it is possible to accept uncertainty and potential inaccuracies caused by non-idempotent messages. In some cases the data doesn't have to be consistent at all times. In other systems there might be mechanisms that allow for dealing with inconsistencies afterwards. | ||
| In some systems it is possible to accept uncertainty and potential inaccuracies caused by non-idempotent messages. In some cases the data doesn't have to be consistent at all times. In other systems there might be mechanisms that allow for dealing with inconsistencies afterward. |
Contributor
There was a problem hiding this comment.
only just found out this is a difference between American and English
| In some systems it is possible to accept uncertainty and potential inaccuracies caused by non-idempotent messages. In some cases the data doesn't have to be consistent at all times. In other systems there might be mechanisms that allow for dealing with inconsistencies afterwards. | ||
| In some systems it is possible to accept uncertainty and potential inaccuracies caused by non-idempotent messages. In some cases the data doesn't have to be consistent at all times. In other systems there might be mechanisms that allow for dealing with inconsistencies afterward. | ||
|
|
||
| Although that might seem unacceptable for many programmers, in the end it is a business decision. It's always recommended to talk to business experts and double-check their expectations. |
Contributor
There was a problem hiding this comment.
Suggested change
| Although that might seem unacceptable for many programmers, in the end it is a business decision. It's always recommended to talk to business experts and double-check their expectations. | |
| This might seem unacceptable for many programmers, but in the end it is a business decision. It's always recommended to talk to business owners/experts and double-check their expectations. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.