mysql 如何在sqlx中建立和提交多查询事务?

hrirmatl  于 2023-11-16  发布在  Mysql
关注(0)|答案(2)|浏览(130)

sqlx中有一个Transaction类型,它允许你在一个事务中运行多个查询。
我试图弄清楚如何做到这一点,遗憾的是没有文档,尽管有自动生成的API文档。
我的第一次尝试:

async fn insert_user() {
    let pool: sqlx::Pool<sqlx::MySql> =
        futures::executor::block_on(crate::db::open_mariadb_pool()).unwrap();
    use sqlx::Acquire;
    let mut conn = pool.acquire().await.unwrap();
    let tx = conn.begin().await.unwrap();
    let insert_query = sqlx::query("INSERT INTO user (email, email_verification_secret, email_verified, password_hash, hourly_rate)
VALUES (?, ?, ?, ?, ?);"
    )
        .bind("[email protected]")
        .bind(false)
        .bind(123)
        .bind("pwhash")
        .bind(20);
    let get_row_query = sqlx::query::<sqlx::MySql>("SELECT * FROM user WHERE id = LAST_INSERT_ID();");
    insert_query.execute(tx);
    get_row_query.execute(tx);
    tx.commit();
}

字符串
生成以下错误:

error[E0277]: the trait bound `Transaction<'_, MySql>: Executor<'_>` is not satisfied
  --> src/controller_user.rs:86:26
   |
86 |     insert_query.execute(tx);
   |                          ^^ the trait `Executor<'_>` is not implemented for `Transaction<'_, MySql>`
   |
   = help: the following implementations were found:
             <&'t mut Transaction<'c, MySql> as Executor<'t>>

error[E0277]: the trait bound `Transaction<'_, MySql>: Executor<'_>` is not satisfied
  --> src/controller_user.rs:87:27
   |
87 |     get_row_query.execute(tx);
   |                           ^^ the trait `Executor<'_>` is not implemented for `Transaction<'_, MySql>`
   |
   = help: the following implementations were found:
             <&'t mut Transaction<'c, MySql> as Executor<'t>>


我真的不知道从哪里开始思考这个问题-但我无法从自动生成的API文档中找到答案。

kq4fsx7k

kq4fsx7k1#

在函数it_can_work_with_transactions中的测试tests/mssql/mssql.rs中有一个示例用法。
用法似乎是:

let mut tx = conn.begin().await?;

sqlx::query("INSERT INTO _sqlx_users_1922 (id) VALUES (@p1)")
    .bind(10_i32)
    .execute(&mut tx)
    .await?;

tx.commit().await?;

字符串
您正在做的事情和这段代码之间唯一明显的区别是传递一个可变引用,而不是将值作为参数传递给execute
考虑到这一点,如果我们仔细看你的错误消息,这正是它所说的。在用.

... the trait `Executor<...>` is not implemented for `Transaction<...>`
   |
... the following implementations were found:
             &mut Transaction<...> as Executor<...>

velaa5lx

velaa5lx2#

要更新此答案,版本7.0现在需要

// In 0.7, `Transaction` can no longer implement `Executor` directly,
// so it must be dereferenced to the internal connection type.
.execute(&mut *transaction)

字符串
https://github.com/launchbadge/sqlx/blob/main/examples/postgres/transaction/src/main.rs

相关问题