sea-orm icon indicating copy to clipboard operation
sea-orm copied to clipboard

transaction use probelm with state

Open joebnb opened this issue 1 year ago • 1 comments

hello

im a new of rust and sea-rom, when i using axum as web server framework have some problem of it.

i using sea-orm connection as axum state of whole app.all was working fine,except transaction.

because it's mutable.but axum state to keep mutex state need RwLock, i think it's will affect performance of muti-thread.

axum mutable state docs: https://github.com/tokio-rs/axum/pull/1759/files#diff-84223c57f305fae05708a2bb1a4009db01ce168ef6d56ba1631ed6e3436507d3

    match query_data.unwrap() {
        Some(data) => {
            let transaction = &_state.conn.begin().await.unwrap(); // here is  &sea_orm::DatabaseTransaction

            let mut data::ActiveModel = data.into();

            let result = data.save(transaction).await;
            transaction.commit().await; // here will throw cannot move out of `*transaction` which is behind a shared reference
// move occurs because `*transaction` has type `DatabaseTransaction`, which does not implement the `Copy` trait

            match result {
                Ok(_) => http::response_basic(Some("()".to_string()), None, None),
                Err(err) => http::response_500(Some(err.to_string())),
            }
        }
        None => http::response_500(Some("no update target found".to_owned())),
    }
// if i change  line 3 to 
  let transaction = &_state.conn.begin().await.unwrap(); // if here is  &&mut sea_orm::DatabaseTransaction this type was not satisify 
  
// when do save will throw:
  let result = data.save(transaction).await; // the trait bound `&mut DatabaseTransaction: ConnectionTrait` is not satisfied
// the trait `ConnectionTrait` is not implemented for `&mut DatabaseTransaction`

how to use transaction in this case,will it must make a Rwlock when do transaction to stop other thread to use connection ?

https://github.com/SeaQL/sea-orm/pull/2043 i dont know did this will help me

joebnb avatar Mar 16 '24 18:03 joebnb

try like this

    async fn save(&self, transaction : &DatabaseTransaction, customer: Customer) -> AppResult<Uuid> {
        // 转po
        let user = (po::user::ActiveModel {
            user_id: Set(Uuid::new_v4()),
            username: Set(customer.username().to_owned()),
            email: Set(customer.email().to_owned()),
            password: Set(password::hash(customer.password().to_string()).await?),
            is_deleted: Set(1),
            is2fa: Set(0),
            create_time: Set(Utc::now().naive_utc()),
            ..Default::default()
        }).save(transaction).await?;
        Ok(user.user_id)
    }

VCCICCV avatar Nov 24 '24 17:11 VCCICCV

The connection is a wrapper of Arc, you can simply clone it.

Huliiiiii avatar Aug 10 '25 21:08 Huliiiiii

thanks for all,now i have basic impact on rust,and this kinds question wasnt question

joebnb avatar Aug 12 '25 11:08 joebnb