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 if

View on GitHub (pinned to 03af8bcc57)

Solutions

  1. Override `get_transaction_depth(&self) -> usize` in your backend implementation, returning the real nesting depth from the driver's state.
  2. If you cannot implement it yet, avoid calling is_in_transaction on that backend; track transaction state in your own wrapper.
  3. If using an official backend (Postgres/MySQL/SQLite) via AnyConnection, upgrade sqlx — shipped backends implement the method; your pinned version may predate it.
  4. 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

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


AI-assisted analysis of transact-rs/sqlx@03af8bcc57 (2026-09-03). Data as JSON: /api/errors/07e0c0b60e4190d6. Report an issue: GitHub.