$atomic/$atOnce
Functionality
Definition
The $atomic
and $atOnce
endpoints allow you to execute multiple actions in a single REST request within a transaction. If any action fails, the entire transaction is canceled, ensuring data consistency and integrity.
This is crucial for maintaining data integrity, especially when dealing with operations that must be executed as a unit.
Syntax
POST /rest/{{dataClass}}?$atomic=true
or
POST /rest/{{dataClass}}?$atOnce=true
Combining with Other Parameters
You can combine $atomic
or $atOnce
with other parameters to refine your data manipulation operations:
-
$filter: Ensure that filtered data updates are transactional.
-
$orderby: Maintain transactional integrity while sorting data.
Use Cases
Updating Multiple Records
Updating multiple records atomically to ensure all or none of the changes are applied:
Request:
POST /rest/Users?$atomic=true
POST data:
[
{
"__KEY": "1",
"Name": "John"
},
{
"__KEY": "2",
"Name": "Jane"
}
]
If any record update fails, neither record is updated.
In a scenario where one of the entities in the transaction fails, the entire transaction is canceled, and no changes are saved. If an error occurs for the user with '__KEY: 222', the response would indicate that the transaction failed:
POST data:
[
{
"__KEY": "1",
"Name": "John"
},
{
"__KEY": "222",
"Name": "Jane"
}
]
If there is an error in one of the entities, the entire transaction is canceled, and no changes are saved. For example, if the second entity has an error:
{
"__STATUS": {
"success": true
},
"__KEY": "1",
"__STAMP": 4,
"uri": "/rest/Users[1]",
"__TIMESTAMP": "!!2024-05-20!!",
"ID": 1,
"Name": "John",
"Email": "user1@example.com",
"Orders": {
"__deferred": {
"uri": "/rest/Users[1]/Orders?$expand=Orders"
}
},
"profilePicture": {
"__deferred": {
"uri": "/rest/Users[1]/profilePicture?$binary=true&$version=4&$expand=profilePicture"
}
},
"__ERROR": [
{
"message": "Error code: 1542 (dbmg)\nCannot find entity with \"222\" key in the \"Users\" dataclass\nDatabase Engine\nDatabase Engine\ntask 48, name: 'REST Handler: '\n",
"componentSignature": "dbmg",
"errCode": 1542
}
]
}
Even though the first entity has valid data, it is not saved due to the error in the second entity. If you reload the first entity, you will see the previous values, confirming that no changes were made.
Inserting Multiple Records
Inserting multiple records in a single transaction:
Request:
POST /rest/Users?$method=insert&$atOnce=true
POST data:
[
{
"firstname": "Alice",
"lastname": "Brown"
},
{
"firstname": "Bob",
"lastname": "White"
}
]
Both records are inserted only if both operations succeed.
Deleting Multiple Records
Deleting multiple records within a transaction:
Request:
POST /rest/Users?$method=delete&$atomic=true
POST data:
[
{
"__KEY": "200"
},
{
"__KEY": "201"
}
]
Both records are deleted only if both deletions succeed.
Best Practices
-
Use Only When Necessary: Employ
$atomic
or$atOnce
only for operations that require strict transactional integrity. -
Minimize Transaction Scope: Limit the scope of transactions to essential actions to reduce the potential for conflicts and errors.
-
Combine with Other Parameters: Leverage other query parameters (
$filter
,$orderby
) to optimize data manipulation and performance.