Transactions let you stage multiple database operations and apply them together, atomically. Use transactions to keep related changes consistent, even when they span multiple databases and tables.
How transactions work
- Call the createTransaction method to create a transaction. This will return a transaction model, including its ID.
- Stage operations by passing the
transactionId
parameter to supported row, bulk, and atomic numeric methods. You can stage many operations at once with the createOperations method. - Call the updateTransaction method to commit or roll back.
On commit, Appwrite replays all staged logs in order inside a real database transaction. Staged operations see earlier staged changes (read your own writes). If any affected row changed outside your transaction, the commit fails with a conflict.
Scope and limitations
You can stage operations across any database and table within the same transaction. Schema operations (for example, adding or removing columns) are not included in transactions.
Limits
The maximum number of operations you can stage per transaction depends on your plan:
Plan | Max operations per transaction |
Free | 100 |
Pro | 1,000 |
Scale | 2,500 |
Create a transaction
Call the createTransaction
method to begin. It returns a transaction model that includes $id
. Pass this ID as transactionId
to subsequent operations.
Stage operations
Add the transactionId
parameter to supported methods to stage them instead of immediately persisting.
When you pass transactionId
, Appwrite writes the operation to an internal staging area. The target table is not modified until you commit the transaction.
Stage single operations
Create, update, upsert, delete, and atomic numeric operations accept transactionId
, as well as their bulk versions (createRows, updateRows, upsertRows, deleteRows).
Stage many with createOperations
Use the createOperations
method to stage multiple operations across databases and tables in a single request. Provide an array of operation objects:
[
{
"action": "create|update|upsert|increment|decrement|delete|bulkCreate|bulkUpdate|bulkUpsert|bulkDelete",
"databaseId": "<DATABASE_ID>",
"tableId|collectionId": "<TABLE_ID|COLLECTION_ID>",
"rowId|documentId": "<ROW_ID|DOCUMENT_ID>",
"data": {}
}
]
Provide data for each action (createOperations)
Create, update, and upsert
Pass a raw data object.
{ "name": "Walter" }
Increment and decrement
Pass a value and optionally min
/max
bounds.
{ "value": 1, "min": 0, "max": 1000, "column": "<COLUMN_NAME>" }
Bulk create and bulk upsert
Pass an array of raw data objects.
[{ "$id": "123", "name": "Walter" }]
Bulk update
Pass queries and the data to apply.
{ "queries": [{"method": "equal", "attribute": "status", "values": ["draft"]}], "data": { "status": "published" } }
Bulk delete
Pass queries to select rows to delete.
{ "queries": [{"method": "equal", "attribute": "archived", "values": [true]}] }
Commit or roll back
When you are done staging operations, call the updateTransaction
method to finalize the transaction.
Handle conflicts
On commit, Appwrite verifies that rows affected by your transaction haven’t changed externally since they were staged. If a conflicting change is detected, the commit fails with a conflict error. Resolve the conflict (for example, refetch and re-stage) and try again.
Best practices
Keep transactions short-lived to reduce the likelihood of conflicts. Stage related updates in the order they must be applied. Prefer createOperations
when you need to stage many changes across multiple tables.
Explore the API references