{"record":{"id":"07e0c0b60e4190d6","repo":"transact-rs/sqlx","slug":"get-transaction-depth-is-not-implemented-for-thi","errorCode":null,"errorMessage":"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.","messagePattern":"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\\.","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sqlx-core/src/any/connection/backend.rs","lineNumber":50,"sourceCode":"    ///\n    /// If we are already inside a transaction and `statement.is_some()`, then\n    /// `Error::InvalidSavePoint` is returned without running any statements.\n    fn begin(&mut self, statement: Option<SqlStr>) -> BoxFuture<'_, crate::Result<()>>;\n\n    fn commit(&mut self) -> BoxFuture<'_, crate::Result<()>>;\n\n    fn rollback(&mut self) -> BoxFuture<'_, crate::Result<()>>;\n\n    fn start_rollback(&mut self);\n\n    /// Returns the current transaction depth.\n    ///\n    /// Transaction depth indicates the level of nested transactions:\n    /// - Level 0: No active transaction.\n    /// - Level 1: A transaction is active.\n    /// - Level 2 or higher: A transaction is active and one or more SAVEPOINTs have been created within it.\n    fn get_transaction_depth(&self) -> usize {\n        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.\");\n    }\n\n    /// Checks if the connection is currently in a transaction.\n    ///\n    /// This method returns `true` if the current transaction depth is greater than 0,\n    /// indicating that a transaction is active. It returns `false` if the transaction depth is 0,\n    /// meaning no transaction is active.\n    #[inline]\n    fn is_in_transaction(&self) -> bool {\n        self.get_transaction_depth() != 0\n    }\n\n    /// The number of statements currently cached in the connection.\n    fn cached_statements_size(&self) -> usize {\n        0\n    }\n\n    /// Removes all statements from the cache, closing them on the server if","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/transact-rs/sqlx/blob/03af8bcc5711a1935580a54bea249c219a0c217d/sqlx-core/src/any/connection/backend.rs#L32-L68","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (custom backend)\nimpl AnyConnectionBackend for MyBackend {\n    /* get_transaction_depth not overridden */\n}\n\n// after\nimpl AnyConnectionBackend for MyBackend {\n    fn get_transaction_depth(&self) -> usize {\n        self.txn_stack.len() // driver's actual nesting depth\n    }\n}","handlingStrategy":"validation","validationCode":"// Guard before calling is_in_transaction on an `any` connection:\nfn supports_txn_depth<B: AnyConnectionBackend>(b: &B) -> bool {\n    // only call get_transaction_depth on backends known to implement it\n    true\n}","typeGuard":null,"tryCatchPattern":"// unimplemented! panics are not recoverable via Result; avoid the call:\n// Instead of any_conn.is_in_transaction(), track state in your wrapper:\nstruct ManagedConn { in_txn: std::cell::Cell<bool>, /* ... */ }","preventionTips":["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"],"tags":["any-driver","transactions","trait-implementation","sqlx"],"backgroundTag":"unimplemented-trait-method","analyzedSha":"03af8bcc5711a1935580a54bea249c219a0c217d","analyzedAt":"2026-09-03T15:01:28.752Z","contentChangedAt":"2026-09-03T15:01:28.752Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}