Safe execution
To avoid remembering to commit and manually handling when to abort a transaction, prefer using the safe execution.
The safe execution allows to execute multiple operations in a block and make sure the transaction is either committed or aborted.
#![allow(unused_variables)] fn main() { let database_connection = DatabaseConnection::builder() .build().await.unwrap(); // Instantiate a new transaction let transaction = Transaction::new(&database_connection).await.unwrap(); // Safely execute operations: let output = transaction.safe_execute(|transaction_connection| async move { // We use the provided `transaction_connection` instead of the classic connection DatabaseRecord::create(Dish { name: "Pizza".to_string(), price: 10, }, &transaction_connection).await?; DatabaseRecord::create(Dish { name: "Pasta".to_string(), price: 8, }, &transaction_connection).await?; DatabaseRecord::create(Dish { name: "Sandwich".to_string(), price: 5, }, &transaction_connection).await?; // You can return any type of data here Ok(()) }).await.unwrap(); // The output allows to check the transaction state: Committed or Aborted assert!(output.is_committed()); }
If an operation fails in the safe_execute
block the transaction will be aborted and every operation cancelled.
Don't use
unwrap()
or any panicking functions in the block as the transaction won't be aborted.
The safe_execute
method returns a TransactionOutput
if everything went correctly (No Database or connection errors).
This output allows to check the state of the transaction, Aborted or Committed and retrieve the result of the block
stored as a generic.
Note: Transactions can be committed multiple times, so feel free to use multiple safe execution blocks.
Warning: An aborted transaction can no longer be committed ! Make sure to handle the
TransactionOuput
cases.