diff --git a/examples/postgres/transaction/src/main.rs b/examples/postgres/transaction/src/main.rs index 50539fe2ac..763bc9e82d 100644 --- a/examples/postgres/transaction/src/main.rs +++ b/examples/postgres/transaction/src/main.rs @@ -1,14 +1,9 @@ use sqlx::query; -#[async_std::main] -async fn main() -> Result<(), Box> { - let conn_str = - std::env::var("DATABASE_URL").expect("Env var DATABASE_URL is required for this example."); - let pool = sqlx::PgPool::connect(&conn_str).await?; - - let mut transaction = pool.begin().await?; - - let test_id = 1; +async fn insert_and_verify( + transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + test_id: i64, +) -> Result<(), Box> { query!( r#"INSERT INTO todos (id, description) VALUES ( $1, $2 ) @@ -16,22 +11,94 @@ async fn main() -> Result<(), Box> { test_id, "test todo" ) - .execute(&mut transaction) + .execute(&mut *transaction) .await?; - // check that inserted todo can be fetched + // check that inserted todo can be fetched inside the uncommitted transaction let _ = query!(r#"SELECT FROM todos WHERE id = $1"#, test_id) - .fetch_one(&mut transaction) + .fetch_one(transaction) .await?; - transaction.rollback(); + Ok(()) +} + +async fn explicit_rollback_example( + pool: &sqlx::PgPool, + test_id: i64, +) -> Result<(), Box> { + let mut transaction = pool.begin().await?; + + insert_and_verify(&mut transaction, test_id).await?; + + transaction.rollback().await?; + + Ok(()) +} + +async fn implicit_rollback_example( + pool: &sqlx::PgPool, + test_id: i64, +) -> Result<(), Box> { + let mut transaction = pool.begin().await?; + + insert_and_verify(&mut transaction, test_id).await?; + + // no explicit rollback here but the transaction object is dropped at the end of the scope + Ok(()) +} + +async fn commit_example( + pool: &sqlx::PgPool, + test_id: i64, +) -> Result<(), Box> { + let mut transaction = pool.begin().await?; + + insert_and_verify(&mut transaction, test_id).await?; + + transaction.commit().await?; - // check that inserted todo is now gone + Ok(()) +} + +#[async_std::main] +async fn main() -> Result<(), Box> { + let conn_str = + std::env::var("DATABASE_URL").expect("Env var DATABASE_URL is required for this example."); + let pool = sqlx::PgPool::connect(&conn_str).await?; + + let test_id = 1; + + // remove any old values that might be in the table already with this id from a previous run + let _ = query!(r#"DELETE FROM todos WHERE id = $1"#, test_id) + .execute(&pool) + .await?; + + explicit_rollback_example(&pool, test_id).await?; + + // check that inserted todo is not visible outside the transaction after explicit rollback let inserted_todo = query!(r#"SELECT FROM todos WHERE id = $1"#, test_id) .fetch_one(&pool) .await; assert!(inserted_todo.is_err()); + implicit_rollback_example(&pool, test_id).await?; + + // check that inserted todo is not visible outside the transaction after implicit rollback + let inserted_todo = query!(r#"SELECT FROM todos WHERE id = $1"#, test_id) + .fetch_one(&pool) + .await; + + assert!(inserted_todo.is_err()); + + commit_example(&pool, test_id).await?; + + // check that inserted todo is visible outside the transaction after commit + let inserted_todo = query!(r#"SELECT FROM todos WHERE id = $1"#, test_id) + .fetch_one(&pool) + .await; + + assert!(inserted_todo.is_ok()); + Ok(()) }