Skip to main content

sqlx_sqlserver/
transaction.rs

1use sqlx_core::database::Database;
2use sqlx_core::error::Error;
3use sqlx_core::sql_str::SqlStr;
4use sqlx_core::transaction::TransactionManager;
5
6use crate::{Mssql, MssqlConnection};
7
8/// SQL Server transaction manager.
9pub struct MssqlTransactionManager;
10
11impl TransactionManager for MssqlTransactionManager {
12    type Database = Mssql;
13
14    async fn begin(conn: &mut MssqlConnection, statement: Option<SqlStr>) -> Result<(), Error> {
15        let sql = statement.unwrap_or_else(|| {
16            if conn.transaction_depth() == 0 {
17                SqlStr::from_static("BEGIN TRANSACTION")
18            } else {
19                SqlStr::from_static("SAVE TRANSACTION sqlx_savepoint")
20            }
21        });
22
23        conn.run_sql_batch(sql.as_str()).await?;
24        conn.increment_transaction_depth();
25        Ok(())
26    }
27
28    async fn commit(conn: &mut MssqlConnection) -> Result<(), Error> {
29        if conn.transaction_depth() == 1 {
30            conn.run_sql_batch("COMMIT TRANSACTION").await?;
31            conn.decrement_transaction_depth();
32        } else if conn.transaction_depth() > 1 {
33            conn.decrement_transaction_depth();
34        }
35
36        Ok(())
37    }
38
39    async fn rollback(conn: &mut MssqlConnection) -> Result<(), Error> {
40        if conn.transaction_depth() == 1 {
41            conn.run_sql_batch("ROLLBACK TRANSACTION").await?;
42            conn.clear_transaction_depth();
43        } else if conn.transaction_depth() > 1 {
44            conn.run_sql_batch("ROLLBACK TRANSACTION sqlx_savepoint")
45                .await?;
46            conn.decrement_transaction_depth();
47        }
48
49        Ok(())
50    }
51
52    fn start_rollback(conn: &mut MssqlConnection) {
53        conn.queue_rollback();
54    }
55
56    fn get_transaction_depth(conn: &<Self::Database as Database>::Connection) -> usize {
57        conn.transaction_depth()
58    }
59}