sqlx_otel/transaction.rs
1use crate::database::Database;
2use crate::pool::SharedState;
3
4/// An in-progress database transaction instrumented for OpenTelemetry.
5///
6/// Wraps a `sqlx::Transaction` and propagates the connection-level attributes and metric
7/// instruments. Pass `&mut transaction` directly to `SQLx` query builders – the
8/// `sqlx::Executor` impl on `&mut Transaction` produces the same per-operation spans and
9/// metrics as the parent pool.
10///
11/// Started by [`Pool::begin`](crate::Pool::begin). Call [`commit`](Self::commit) or
12/// [`rollback`](Self::rollback) to finish the transaction; dropping the value without
13/// committing rolls it back implicitly. Use [`with_annotations`](Self::with_annotations) /
14/// [`with_operation`](Self::with_operation) to attach per-query semantic-convention
15/// attributes.
16///
17/// # Example
18///
19/// ```no_run
20/// # #[cfg(feature = "sqlite")]
21/// # async fn _doc() -> Result<(), sqlx::Error> {
22/// # use sqlx_otel::PoolBuilder;
23/// # let pool = PoolBuilder::from(sqlx::SqlitePool::connect(":memory:").await?).build();
24/// let mut tx = pool.begin().await?;
25/// sqlx::query("INSERT INTO orders (id) VALUES (1)")
26/// .execute(&mut tx)
27/// .await?;
28/// tx.commit().await?;
29/// # Ok(())
30/// # }
31/// ```
32#[derive(Debug)]
33pub struct Transaction<'c, DB: sqlx::Database> {
34 pub(crate) inner: sqlx::Transaction<'c, DB>,
35 pub(crate) state: SharedState,
36}
37
38impl<DB> Transaction<'_, DB>
39where
40 DB: Database,
41{
42 /// Commit the transaction.
43 ///
44 /// # Errors
45 ///
46 /// Returns `sqlx::Error` if the commit fails.
47 pub async fn commit(self) -> Result<(), sqlx::Error> {
48 self.inner.commit().await
49 }
50
51 /// Roll back the transaction.
52 ///
53 /// # Errors
54 ///
55 /// Returns `sqlx::Error` if the rollback fails.
56 pub async fn rollback(self) -> Result<(), sqlx::Error> {
57 self.inner.rollback().await
58 }
59
60 impl_with_annotations_mut!();
61}