with_transaction

Function with_transaction 

Source
pub async fn with_transaction<F, T>(pool: &MySqlPool, f: F) -> Result<T>
where F: for<'a> FnOnce(&'a mut TransactionContext<'_>) -> Pin<Box<dyn Future<Output = Result<T>> + Send + 'a>>, T: Send,
Expand description

Executes a function within a database transaction.

This function handles the transaction lifecycle automatically:

  • Begins a transaction
  • Executes the provided function
  • Commits on success
  • Rolls back on error

§Type Parameters

  • F - A function that takes a mutable TransactionContext and returns a pinned future
  • T - The return type of the function (must be Send)

§Arguments

  • pool - The MySQL connection pool
  • f - The function to execute within the transaction

§Returns

Returns the result of the function execution, or an error if the transaction fails.

§Examples

§Basic Usage

use sqlx::MySqlPool;
use sqlx_transaction_manager::with_transaction;

with_transaction(&pool, |tx| {
    Box::pin(async move {
        sqlx::query("INSERT INTO users (name) VALUES (?)")
            .bind("Alice")
            .execute(tx.as_executor())
            .await?;
        Ok::<_, sqlx::Error>(())
    })
}).await?;

§Multiple Operations

use sqlx::MySqlPool;
use sqlx_transaction_manager::with_transaction;

let user_id = with_transaction(&pool, |tx| {
    Box::pin(async move {
        let result = sqlx::query("INSERT INTO users (name) VALUES (?)")
            .bind("Bob")
            .execute(tx.as_executor())
            .await?;

        let user_id = result.last_insert_id() as i64;

        sqlx::query("INSERT INTO profiles (user_id, bio) VALUES (?, ?)")
            .bind(user_id)
            .bind("Software Developer")
            .execute(tx.as_executor())
            .await?;

        Ok::<_, sqlx::Error>(user_id)
    })
}).await?;

§Error Handling

use sqlx::MySqlPool;
use sqlx_transaction_manager::with_transaction;

let result = with_transaction(&pool, |tx| {
    Box::pin(async move {
        sqlx::query("INSERT INTO users (name) VALUES (?)")
            .bind("Charlie")
            .execute(tx.as_executor())
            .await?;

        // If this fails, the entire transaction is rolled back
        sqlx::query("INVALID SQL")
            .execute(tx.as_executor())
            .await?;

        Ok::<_, sqlx::Error>(())
    })
}).await;

assert!(result.is_err()); // Transaction was rolled back