transact-rs/sqlx · error
get_transaction_depth() is not implemented for this backend.
Error message
get_transaction_depth() is not implemented for this backend. This is a provided method to avoid a breaking change, but it will become a required method in version 0.9 and later.
What it means
AnyConnectionBackend::get_transaction_depth() (sqlx-core/src/any/connection/backend.rs) is a provided trait method that currently calls unimplemented!(). It exists only to avoid a breaking change for third-party backend implementations; sqlx plans to make it a required method in 0.9. Calling is_in_transaction() on a backend that did not override the method therefore panics with this message.
Source
Thrown at sqlx-core/src/any/connection/backend.rs:50
///
/// If we are already inside a transaction and `statement.is_some()`, then
/// `Error::InvalidSavePoint` is returned without running any statements.
fn begin(&mut self, statement: Option<SqlStr>) -> BoxFuture<'_, crate::Result<()>>;
fn commit(&mut self) -> BoxFuture<'_, crate::Result<()>>;
fn rollback(&mut self) -> BoxFuture<'_, crate::Result<()>>;
fn start_rollback(&mut self);
/// Returns the current transaction depth.
///
/// Transaction depth indicates the level of nested transactions:
/// - Level 0: No active transaction.
/// - Level 1: A transaction is active.
/// - Level 2 or higher: A transaction is active and one or more SAVEPOINTs have been created within it.
fn get_transaction_depth(&self) -> usize {
unimplemented!("get_transaction_depth() is not implemented for this backend. This is a provided method to avoid a breaking change, but it will become a required method in version 0.9 and later.");
}
/// Checks if the connection is currently in a transaction.
///
/// This method returns `true` if the current transaction depth is greater than 0,
/// indicating that a transaction is active. It returns `false` if the transaction depth is 0,
/// meaning no transaction is active.
#[inline]
fn is_in_transaction(&self) -> bool {
self.get_transaction_depth() != 0
}
/// The number of statements currently cached in the connection.
fn cached_statements_size(&self) -> usize {
0
}
/// Removes all statements from the cache, closing them on the server ifView on GitHub (pinned to 03af8bcc57)
Solutions
- Override `get_transaction_depth(&self) -> usize` in your backend implementation, returning the real nesting depth from the driver's state.
- If you cannot implement it yet, avoid calling is_in_transaction on that backend; track transaction state in your own wrapper.
- If using an official backend (Postgres/MySQL/SQLite) via AnyConnection, upgrade sqlx — shipped backends implement the method; your pinned version may predate it.
- Prepare for 0.9: the method becomes required, so implement it now to avoid a compile break later.
Example fix
// before (custom backend)
impl AnyConnectionBackend for MyBackend {
/* get_transaction_depth not overridden */
}
// after
impl AnyConnectionBackend for MyBackend {
fn get_transaction_depth(&self) -> usize {
self.txn_stack.len() // driver's actual nesting depth
}
} Defensive patterns
Strategy: validation
Validate before calling
// Guard before calling is_in_transaction on an `any` connection:
fn supports_txn_depth<B: AnyConnectionBackend>(b: &B) -> bool {
// only call get_transaction_depth on backends known to implement it
true
} Try / catch
// unimplemented! panics are not recoverable via Result; avoid the call:
// Instead of any_conn.is_in_transaction(), track state in your wrapper:
struct ManagedConn { in_txn: std::cell::Cell<bool>, /* ... */ } Prevention
- If you implement AnyConnectionBackend, always override get_transaction_depth now (required in 0.9)
- Track transaction state in your own abstraction instead of relying on is_in_transaction for custom backends
- Keep sqlx and any third-party backend crates on compatible versions
When it happens
Trigger: Calling `any_conn.is_in_transaction()` (or anything that routes through get_transaction_depth, e.g. nested-transaction helpers on AnyConnection) when the underlying backend impl (a custom or not-yet-updated driver) does not override get_transaction_depth.
Common situations: Custom AnyConnectionBackend implementations written against sqlx 0.8's trait where the method was newly added with a default panicking body; code migrated to use the new is_in_transaction API on the `any` driver; third-party backend crates lagging behind core.
Related errors
- No drivers installed. Please see the documentation in `sqlx:
- Cannot use both flatten and json
- Cannot use both try from and json nullable
- one of the `runtime-*-native-tls` or `runtime-*-rustls` feat
- this functionality requires a Tokio context
AI-assisted analysis of transact-rs/sqlx@03af8bcc57 (2026-09-03).
Data as JSON: /api/errors/07e0c0b60e4190d6.
Report an issue: GitHub.