pub async fn with_nested_transaction<F, T>(
tx_ctx: &mut TransactionContext<'_>,
f: F,
) -> Result<T>Expand description
Executes a nested transaction using savepoints.
This function allows you to create a transaction within an existing transaction by using MySQL savepoints. If the nested transaction fails, only operations since the savepoint are rolled back.
§Type Parameters
F- A function that takes a mutableTransactionContextand returns a futureFut- The future type returned by the functionT- The return type (must beSend)
§Arguments
tx_ctx- The existing transaction contextf- The function to execute within the nested transaction
§Returns
Returns the result of the function execution, or an error if the savepoint operation fails.
§Examples
use sqlx::MySqlPool;
use sqlx_transaction_manager::{with_transaction, with_nested_transaction};
with_transaction(&pool, |tx| {
Box::pin(async move {
// Outer transaction operations
sqlx::query("INSERT INTO users (name) VALUES (?)")
.bind("Alice")
.execute(tx.as_executor())
.await?;
// Nested transaction with savepoint
let nested_result = with_nested_transaction(tx, |nested_tx| {
Box::pin(async move {
sqlx::query("INSERT INTO logs (message) VALUES (?)")
.bind("User created")
.execute(nested_tx.as_executor())
.await?;
Ok::<_, sqlx::Error>(())
})
}).await;
// If nested transaction fails, outer transaction can still succeed
if nested_result.is_err() {
println!("Logging failed, but user creation will still commit");
}
Ok::<_, sqlx::Error>(())
})
}).await?;§Note
MySQL doesn’t support true nested transactions. This function uses SAVEPOINTs
to simulate nested transaction behavior. The savepoint name is nested_tx.