-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
sqlx lost transaction support starting version 0.7.0 #2699
Comments
Please read the 0.7 changelog and look at the current examples. This is not a bug, just a breaking change how transactions are used |
@goodjius . Here is the relevant part of the changelog mentioned by @dragonnn
What helped was using My example self.conn.transaction(|tx| Box::pin(async move {
sqlx::query(
r#"...
"#,
).bind(...)
.execute(tx.as_mut())
.await?;
Ok::<_, eyre::Error>(())
})).await?; In your example this would be: let mut tx = pool.begin().await?;
let res = sqlx::query("DELETE FROM \"testcases\" WHERE id = $1")
.bind(id)
.execute(tx.as_mut()) // <-- here
.await?
.rows_affected();
tx.commit().await?; |
Hi, sorry for bumping this old issue. I stumbled across the same problem, I wanted to use a transaction in a personal project and I wasn't able to get it to work at first. The examples in this repo were able to help me and I got it working, but I think it would be nice to add a short example on how to use Is that a good idea? If yes, I would submit a PR 😄. |
@Lachstec Yes please do it. |
@fosskers Okay, I will get to it if I find some time today. |
@fosskers I've submitted a PR where I added a Snippet inspired by the one in this issue, hope that it is fine like that :) |
Currently, there are only these scenarios available: /// Scenario 1: pool/tx interface + multiple queries
///
/// TLDR we should never want this ambiguity
///
/// for a single query this one will work just fine
pub async fn run(executor: impl Executor<'_, Database = Postgres>) {
sqlx::query("SELECT 1").execute(executor).await.unwrap();
sqlx::query("SELECT 1").execute(executor).await.unwrap();
// error: ^^^^^^^^ value used after move
}
/// Scenario 2: we want to use the same executor for multiple queries
///
/// we can demand Executor: Copy
pub async fn run_copy(executor: impl Executor<'_, Database = Postgres> + std::marker::Copy) {
sqlx::query("SELECT 1").execute(executor).await.unwrap();
run_copy(executor).await;
sqlx::query("SELECT 1").execute(executor).await.unwrap();
}
/// Scenario 3: we want to use the same executor for multiple queries
///
/// We can specify an executor type as a Transaction explicitly
/// This allows us to use transactions as normal with multiple queries
#[async_recursion::async_recursion]
pub async fn run_atomic(executor: &mut Transaction<'_, Postgres>) {
sqlx::query("SELECT 1").execute(&mut **executor).await.unwrap();
run_atomic(executor).await;
sqlx::query("SELECT 1").execute(&mut **executor).await.unwrap();
}
pub async fn outer_logic(pool: sqlx::Pool<Postgres>) {
{
// Scenario 2 use
// w/o transaction -- works
run_copy(&pool).await;
run_copy(&pool).await;
// with transaction won't work
}
{
// Scenario 3 use
// w/o transaction
// run_atomic(&pool).await; // error: cannot use pool
// with transaction -- works
let mut tx = pool.begin().await.unwrap();
sqlx::query("SELECT 1").execute(&mut *tx).await.unwrap();
run_atomic(&mut tx).await;
sqlx::query("SELECT 1").execute(&mut *tx).await.unwrap();
tx.commit().await.unwrap();
}
} I prefer Scenario 3 as universal. And the cost is small: you should make every query in transactions, which is not a big deal most of the time. |
Bug Description
Get error: .fetch_one(&mut tx)
| --------- ^^^^^^^ the trait
Executor<'_>
is not implemented for&mut Transaction<'_, Sqlite>
.This is no problem with sqlx 0.6.x.
Compiler start to complain starting 0.7.0
Minimal Reproduction
Info
rustc --version
: 1.71.0The text was updated successfully, but these errors were encountered: