Skip to content

Commit fd4d219

Browse files
authored
fix and extend postgres transaction example (#1636)
1 parent 183e620 commit fd4d219

File tree

1 file changed

+81
-14
lines changed
  • examples/postgres/transaction/src

1 file changed

+81
-14
lines changed
+81-14
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,104 @@
11
use sqlx::query;
22

3-
#[async_std::main]
4-
async fn main() -> Result<(), Box<dyn std::error::Error>> {
5-
let conn_str =
6-
std::env::var("DATABASE_URL").expect("Env var DATABASE_URL is required for this example.");
7-
let pool = sqlx::PgPool::connect(&conn_str).await?;
8-
9-
let mut transaction = pool.begin().await?;
10-
11-
let test_id = 1;
3+
async fn insert_and_verify(
4+
transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>,
5+
test_id: i64,
6+
) -> Result<(), Box<dyn std::error::Error>> {
127
query!(
138
r#"INSERT INTO todos (id, description)
149
VALUES ( $1, $2 )
1510
"#,
1611
test_id,
1712
"test todo"
1813
)
19-
.execute(&mut transaction)
14+
.execute(&mut *transaction)
2015
.await?;
2116

22-
// check that inserted todo can be fetched
17+
// check that inserted todo can be fetched inside the uncommitted transaction
2318
let _ = query!(r#"SELECT FROM todos WHERE id = $1"#, test_id)
24-
.fetch_one(&mut transaction)
19+
.fetch_one(transaction)
2520
.await?;
2621

27-
transaction.rollback();
22+
Ok(())
23+
}
24+
25+
async fn explicit_rollback_example(
26+
pool: &sqlx::PgPool,
27+
test_id: i64,
28+
) -> Result<(), Box<dyn std::error::Error>> {
29+
let mut transaction = pool.begin().await?;
30+
31+
insert_and_verify(&mut transaction, test_id).await?;
32+
33+
transaction.rollback().await?;
34+
35+
Ok(())
36+
}
37+
38+
async fn implicit_rollback_example(
39+
pool: &sqlx::PgPool,
40+
test_id: i64,
41+
) -> Result<(), Box<dyn std::error::Error>> {
42+
let mut transaction = pool.begin().await?;
43+
44+
insert_and_verify(&mut transaction, test_id).await?;
45+
46+
// no explicit rollback here but the transaction object is dropped at the end of the scope
47+
Ok(())
48+
}
49+
50+
async fn commit_example(
51+
pool: &sqlx::PgPool,
52+
test_id: i64,
53+
) -> Result<(), Box<dyn std::error::Error>> {
54+
let mut transaction = pool.begin().await?;
55+
56+
insert_and_verify(&mut transaction, test_id).await?;
57+
58+
transaction.commit().await?;
2859

29-
// check that inserted todo is now gone
60+
Ok(())
61+
}
62+
63+
#[async_std::main]
64+
async fn main() -> Result<(), Box<dyn std::error::Error>> {
65+
let conn_str =
66+
std::env::var("DATABASE_URL").expect("Env var DATABASE_URL is required for this example.");
67+
let pool = sqlx::PgPool::connect(&conn_str).await?;
68+
69+
let test_id = 1;
70+
71+
// remove any old values that might be in the table already with this id from a previous run
72+
let _ = query!(r#"DELETE FROM todos WHERE id = $1"#, test_id)
73+
.execute(&pool)
74+
.await?;
75+
76+
explicit_rollback_example(&pool, test_id).await?;
77+
78+
// check that inserted todo is not visible outside the transaction after explicit rollback
3079
let inserted_todo = query!(r#"SELECT FROM todos WHERE id = $1"#, test_id)
3180
.fetch_one(&pool)
3281
.await;
3382

3483
assert!(inserted_todo.is_err());
3584

85+
implicit_rollback_example(&pool, test_id).await?;
86+
87+
// check that inserted todo is not visible outside the transaction after implicit rollback
88+
let inserted_todo = query!(r#"SELECT FROM todos WHERE id = $1"#, test_id)
89+
.fetch_one(&pool)
90+
.await;
91+
92+
assert!(inserted_todo.is_err());
93+
94+
commit_example(&pool, test_id).await?;
95+
96+
// check that inserted todo is visible outside the transaction after commit
97+
let inserted_todo = query!(r#"SELECT FROM todos WHERE id = $1"#, test_id)
98+
.fetch_one(&pool)
99+
.await;
100+
101+
assert!(inserted_todo.is_ok());
102+
36103
Ok(())
37104
}

0 commit comments

Comments
 (0)