sqlx_mysql/
transaction.rs

1use futures_core::future::BoxFuture;
2
3use crate::connection::Waiting;
4use crate::error::Error;
5use crate::executor::Executor;
6use crate::protocol::text::Query;
7use crate::{MySql, MySqlConnection};
8
9pub(crate) use sqlx_core::transaction::*;
10
11/// Implementation of [`TransactionManager`] for MySQL.
12pub struct MySqlTransactionManager;
13
14impl TransactionManager for MySqlTransactionManager {
15    type Database = MySql;
16
17    fn begin(conn: &mut MySqlConnection) -> BoxFuture<'_, Result<(), Error>> {
18        Box::pin(async move {
19            let depth = conn.inner.transaction_depth;
20
21            conn.execute(&*begin_ansi_transaction_sql(depth)).await?;
22            conn.inner.transaction_depth = depth + 1;
23
24            Ok(())
25        })
26    }
27
28    fn commit(conn: &mut MySqlConnection) -> BoxFuture<'_, Result<(), Error>> {
29        Box::pin(async move {
30            let depth = conn.inner.transaction_depth;
31
32            if depth > 0 {
33                conn.execute(&*commit_ansi_transaction_sql(depth)).await?;
34                conn.inner.transaction_depth = depth - 1;
35            }
36
37            Ok(())
38        })
39    }
40
41    fn rollback(conn: &mut MySqlConnection) -> BoxFuture<'_, Result<(), Error>> {
42        Box::pin(async move {
43            let depth = conn.inner.transaction_depth;
44
45            if depth > 0 {
46                conn.execute(&*rollback_ansi_transaction_sql(depth)).await?;
47                conn.inner.transaction_depth = depth - 1;
48            }
49
50            Ok(())
51        })
52    }
53
54    fn start_rollback(conn: &mut MySqlConnection) {
55        let depth = conn.inner.transaction_depth;
56
57        if depth > 0 {
58            conn.inner.stream.waiting.push_back(Waiting::Result);
59            conn.inner.stream.sequence_id = 0;
60            conn.inner
61                .stream
62                .write_packet(Query(&rollback_ansi_transaction_sql(depth)))
63                .expect("BUG: unexpected error queueing ROLLBACK");
64
65            conn.inner.transaction_depth = depth - 1;
66        }
67    }
68}