Skip to main content

tank_mysql/
transaction.rs

1use crate::{MySQLConnection, MySQLDriver, MySQLQueryable};
2use mysql_async::TxOpts;
3use tank_core::{Result, Transaction, impl_executor_transaction};
4
5/// Transaction adaptor for MySQL/MariaDB.
6///
7/// Wraps a `mysql_async::Transaction` and implements the `Transaction`/`Executor`
8/// behavior expected by the `tank_core` abstractions.
9pub struct MySQLTransaction<'c> {
10    pub(crate) transaction: MySQLQueryable<mysql_async::Transaction<'c>>,
11}
12
13pub type MariaDBTransaction<'c> = MySQLTransaction<'c>;
14
15impl<'c> MySQLTransaction<'c> {
16    pub async fn new(connection: &'c mut MySQLConnection) -> Result<Self> {
17        Ok(Self {
18            transaction: MySQLQueryable {
19                executor: connection
20                    .conn
21                    .executor
22                    .start_transaction(TxOpts::new())
23                    .await
24                    .map_err(|e| {
25                        log::error!("{:#}", e);
26                        e
27                    })?,
28            },
29        })
30    }
31}
32
33impl_executor_transaction!(MySQLDriver, MySQLTransaction<'c>, transaction);
34
35impl<'c> Transaction<'c> for MySQLTransaction<'c> {
36    async fn commit(self) -> Result<()> {
37        self.transaction
38            .executor
39            .commit()
40            .await
41            .map(|_| ())
42            .map_err(Into::into)
43    }
44
45    async fn rollback(self) -> Result<()> {
46        self.transaction
47            .executor
48            .rollback()
49            .await
50            .map(|_| ())
51            .map_err(Into::into)
52    }
53}