-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix and extend postgres transaction example
- Loading branch information
Showing
1 changed file
with
81 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,37 +1,104 @@ | ||
use sqlx::query; | ||
|
||
#[async_std::main] | ||
async fn main() -> Result<(), Box<dyn std::error::Error>> { | ||
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<dyn std::error::Error>> { | ||
query!( | ||
r#"INSERT INTO todos (id, description) | ||
VALUES ( $1, $2 ) | ||
"#, | ||
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<dyn std::error::Error>> { | ||
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<dyn std::error::Error>> { | ||
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<dyn std::error::Error>> { | ||
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<dyn std::error::Error>> { | ||
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(()) | ||
} |