-
I've been fighting with this for some time now, and I've only been able to manage partial solutions. I have not reached a full solution for what should logically be possible. I understand there is a fundamental difference between a pool and a transaction. A pool can spawn multiple connections which would be reasonable to schedule as separate async blocks running in parallel. A transaction is a single connection which cannot support parallel execution. However, given the common pattern of What I've found that works is: pub async fn foo(conn: &mut PgConnection) -> Result<i32, sqlx::Error> {
sqlx::query("SELECT 1 AS v")
.map(|row: PgRow| row.get("v"))
.fetch_one(conn)
.await
}
let pool: PgPool;
let pool_conn = &mut *pool.acquire().await?;
let mut tx = pool.begin().await?;
foo(pool_conn).await();
foo(pool_conn).await();
foo(&mut tx).await();
foo(&mut tx).await(); Despite being able to call the |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
Firstly, you can avoid the consumption of the pub async fn foo(conn: &mut PgConnection) -> Result<i32, sqlx::Error> {
sqlx::query("<do something else>")
.execute(&mut *conn)
.await?;
sqlx::query("SELECT 1 AS v")
.map(|row: PgRow| row.get("v"))
.fetch_one(&mut *conn)
.await?
} Secondly, if you use pub async fn foo(conn: impl Acquire<Database = Postgres>) -> Result<i32, sqlx::Error> {
// no-op for `PgConnection`, `Transaction`
let mut conn = conn.acquire().await?;
sqlx::query("SELECT 1 AS v")
.map(|row: PgRow| row.get("v"))
.fetch_one(conn)
.await
}
foo(&pool).await?;
foo(&mut tx).await?; |
Beta Was this translation helpful? Give feedback.
-
Any news in v0.6.0? |
Beta Was this translation helpful? Give feedback.
Firstly, you can avoid the consumption of the
&mut PgConnection
if you reborrow:Secondly, if you use
impl Acquire<Database = Postgres>
(so don't constrict theConnection
associated type) then you should be able to use either: