Overview
A transaction contains a sequence of database operations that either all succeed or fail together as a unit to guarantee the ACID (Atomicity, Consistency, Isolation, and Durability) properties.
Transactions are crucial for tasks where data integrity is paramount, such as financial transfers where you need to deduct the transfer amount from one account and increase by that amount for another account.
Currently one session only supports one running transaction.
Transaction Lifecycle and Control
The lifecycle of a transaction follows a clear three-step process:
- START: Start a transaction explicitly.
- EXECUTE: Perform database operations.
- TERMINATE: Commit or rollback the transaction.
- COMMIT: All operations within the transaction are permanently applied to the database.
- ROLLBACK: All operations within the transaction are discarded, and the database state is reverted to its condition before the transaction began.
Write operations in a transaction remain provisional and are not finalized until a COMMIT is executed. Any uncommitted changes can be reverted using ROLLBACK.
Locking
When a transaction occurs, Ultipa takes locks to prevent the data update and deletion operations from later transactions to uphold isolation and consistency.
It is crucial to promptly terminate every transaction (via COMMIT or ROLLBACK). Leaving transactions open for an extended period holds these locks, which can lead to blocking and reducing throughput for other processes.
Transaction Timeout
If a transaction remains idle (meaning no new operations are performed) for a certain duration, Ultipa automatically terminates it via a ROLLBACK.
Showing Transactions
To show running transactions in the database:
SHOW TRANSACTION
Each transaction provides the following essential metadata:
Field |
Description |
---|---|
graph_name |
The name of the graph the transaction is executing against. |
session_id |
The session ID. |
transaction_id |
The transaction ID. |
current_query |
The the last query executed in the transaction. |
start_time |
The time when the transaction was started. |
elapsed_time |
The time that has elapsed since the transaction was started. |
status |
The current state of the graph, which can be NORMAL , LOADING_SNAPSHOT , CREATING , DROPPING , or SCALING . |
extra_info |
Extra information about the transaction. |
Starting Transaction
To start a new transaction for the current graph:
START TRANSACTION
Once a transaction is started, you can perform both read and write operations against the current graph in the transaction.
Rolling Back Transaction
To discard all operations within the transaction and terminate the transaction:
ROLLBACK
Committing Transaction
To apply all operations within the transaction to the database and terminate the transaction:
COMMIT
Examples
The following example demonstrates how to start a transaction and perform three operations:
- Inserts a
Transfer
edge from accountsa78
toa9002
. - Updates the balance of account
a78
. - Updates the balance of account
a9002
Finally, commit the transaction to the database.
START TRANSACTION;
MATCH (a1:Account {_id: "a78"}), (a2:Account {_id: "a9002"})
INSERT (a1)-[:Transfer {amount: 1000, time: local_datetime("2025-11-09 03:02:11")}]->(a2);
MATCH (n:Account {_id: "a78"}) SET n.balance = n.balance - 1000;
MATCH (n:Account {_id: "a9002"}) SET n.balance = n.balance + 1000;
COMMIT;
Alternatively, you can roll back the transaction to discard all changes:
START TRANSACTION;
MATCH (a1:Account {_id: "a78"}), (a2:Account {_id: "a9002"})
INSERT (a1)-[:Transfer {amount: 1000, time: local_datetime("2025-11-09 03:02:11")}]->(a2);
MATCH (n:Account {_id: "a78"}) SET n.balance = n.balance - 1000;
MATCH (n:Account {_id: "a9002"}) SET n.balance = n.balance + 1000;
ROLLBACK;