sqlx/sqlx-sqlite/src/transaction.rs
Kevin Cox 1f7af3abc2
SQLite: fix transaction level accounting with bad custom command. (#3981)
In the previous code the worker would always assume that the custom command worked. However the higher level code would run a check and notice that a transaction was not actually started and raise an error without rolling back the transaction.

This improves the code by moving the transaction check into the worker to ensure that the transaction depth tracker is only modified if the user's custom command actually started a transaction.

Fixes: https://github.com/launchbadge/sqlx/issues/3932
2025-08-18 16:16:52 -07:00

36 lines
1008 B
Rust

use std::future::Future;
use sqlx_core::transaction::TransactionManager;
use sqlx_core::{error::Error, sql_str::SqlStr};
use crate::{Sqlite, SqliteConnection};
/// Implementation of [`TransactionManager`] for SQLite.
pub struct SqliteTransactionManager;
impl TransactionManager for SqliteTransactionManager {
type Database = Sqlite;
async fn begin(conn: &mut SqliteConnection, statement: Option<SqlStr>) -> Result<(), Error> {
conn.worker.begin(statement).await
}
fn commit(conn: &mut SqliteConnection) -> impl Future<Output = Result<(), Error>> + Send + '_ {
conn.worker.commit()
}
fn rollback(
conn: &mut SqliteConnection,
) -> impl Future<Output = Result<(), Error>> + Send + '_ {
conn.worker.rollback()
}
fn start_rollback(conn: &mut SqliteConnection) {
conn.worker.start_rollback().ok();
}
fn get_transaction_depth(conn: &SqliteConnection) -> usize {
conn.worker.shared.get_transaction_depth()
}
}