SQLx wraps database transactions in aDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/launchbadge/sqlx/llms.txt
Use this file to discover all available pages before exploring further.
Transaction struct that tracks whether the transaction is open and ensures it is cleanly closed. You can begin a transaction from a pool or an existing connection, execute queries through it using the Executor trait, and commit or roll back when done. If a Transaction is dropped without being explicitly committed, SQLx automatically initiates a rollback.
Beginning a transaction
Call.begin() on a pool or a connection to start a transaction. From a pool, SQLx acquires a connection and immediately issues a BEGIN:
Transaction<'_, DB> holds the connection for its lifetime. Successive queries inside the same transaction use this single connection.
Executing queries inside a transaction
Transaction implements Deref<Target = DB::Connection>, so you can pass &mut *tx anywhere a mutable connection reference is accepted. Query finalizers accept it as an executor:
Committing and rolling back
Commit
Call
tx.commit().await? to persist all changes made during the transaction. After committing, the Transaction is consumed.Rollback
Call
tx.rollback().await? to discard all changes. After rolling back, the Transaction is consumed.Automatic rollback on drop
If the
Transaction is dropped without calling commit() or rollback(), SQLx calls start_rollback() on the underlying connection. The rollback is queued and executed the next time the connection is used (including when it is returned to the pool).This means that returning early from a function with ? on an error will automatically roll back the transaction:The connection.transaction() helper
For simple cases you can use the transaction() method on a connection, which begins, runs a closure, and commits or rolls back based on whether the closure returns Ok or Err:
Nested transactions and savepoints
When.begin() is called on a connection that already has an active transaction, SQLx creates a savepoint instead of issuing a second BEGIN. Savepoints use automatically generated names (_sqlx_savepoint_1, _sqlx_savepoint_2, …).
Transaction depth is tracked per-connection. Depth 0 means no active transaction; depth 1 means a transaction is active; depth 2 or higher means one or more savepoints are open.
Transactions with the query!() macros
The compile-time macros work with transactions the same way as the query functions — pass &mut *tx as the executor:
Custom BEGIN statements
Some databases support non-standard transaction isolation levels or other options on the BEGIN statement. Use begin_with() to supply a custom statement: