rbatis icon indicating copy to clipboard operation
rbatis copied to clipboard

MySQL中,使用事物守卫时线程会停在 tx.rollback.await.

Open bin-liu opened this issue 3 years ago • 2 comments

测试代码:

    use rbatis::db::{DBPool, DBPoolOptions};
    pub async fn init_db_mysql() -> Rbatis {
        let rb: Rbatis = Rbatis::new();
        let mut opts: DBPoolOptions = DBPoolOptions::new();
        rb.link_opt("mysql://root:[email protected]:3306/mysql", opts).await;
        rb
    }

    //示例-Rbatis使用事务,类似golang defer,守卫如果被回收则 释放事务
    #[tokio::test]
    pub async fn test_tx_mysql_commit_defer() {
        fast_log::init(fast_log::config::Config::new().console());
        let rb: Rbatis = init_db_mysql().await;
        forget_commit(&rb).await.unwrap();
    }

    pub async fn forget_commit(rb: &Rbatis) -> rbatis::core::Result<()> {
        // tx will be commit.when func end
        let mut tx = rb.acquire_begin().await?.defer_async(|mut tx| async move {
            if !tx.is_done() {
                tx.rollback().await;
                println!("tx rollback success!");
            } else {
                println!("don't need rollback!");
            }
        });
        let v = tx
            .exec("update biz_activity set names = '6' where id = 1;", vec![])
            .await?;
        //tx.commit().await;  //if commit, print 'don't need rollback!' ,if not,print 'tx rollback success!'
        return Ok(());
    }

log

running 1 test
2022-07-19 18:11:52.554779 INFO rbatis::plugin::log - [rbatis] [391895266325827584] Exec   ==> update biz_activity set names = '6' where id = 1;
                                                         [rbatis]                      Args   ==> []
2022-07-19 18:11:52.556121 ERROR rbatis::plugin::log - [rbatis] [391895266325827584] ReturnErr  <== error returned from database: 1146 (42S02): Table 'mysql.biz_activity' doesn't exist  src/plugin/log.rs:45

test transaction::test::test_tx_mysql_commit_defer has been running for over 60 seconds

bin-liu avatar Jul 19 '22 10:07 bin-liu

测试代码:

    use rbatis::db::{DBPool, DBPoolOptions};
    pub async fn init_db_mysql() -> Rbatis {
        let rb: Rbatis = Rbatis::new();
        let mut opts: DBPoolOptions = DBPoolOptions::new();
        rb.link_opt("mysql://root:[email protected]:3306/mysql", opts).await;
        rb
    }

    //示例-Rbatis使用事务,类似golang defer,守卫如果被回收则 释放事务
    #[tokio::test]
    pub async fn test_tx_mysql_commit_defer() {
        fast_log::init(fast_log::config::Config::new().console());
        let rb: Rbatis = init_db_mysql().await;
        forget_commit(&rb).await.unwrap();
    }

    pub async fn forget_commit(rb: &Rbatis) -> rbatis::core::Result<()> {
        // tx will be commit.when func end
        let mut tx = rb.acquire_begin().await?.defer_async(|mut tx| async move {
            if !tx.is_done() {
                tx.rollback().await;
                println!("tx rollback success!");
            } else {
                println!("don't need rollback!");
            }
        });
        let v = tx
            .exec("update biz_activity set names = '6' where id = 1;", vec![])
            .await?;
        //tx.commit().await;  //if commit, print 'don't need rollback!' ,if not,print 'tx rollback success!'
        return Ok(());
    }

log

running 1 test
2022-07-19 18:11:52.554779 INFO rbatis::plugin::log - [rbatis] [391895266325827584] Exec   ==> update biz_activity set names = '6' where id = 1;
                                                         [rbatis]                      Args   ==> []
2022-07-19 18:11:52.556121 ERROR rbatis::plugin::log - [rbatis] [391895266325827584] ReturnErr  <== error returned from database: 1146 (42S02): Table 'mysql.biz_activity' doesn't exist  src/plugin/log.rs:45

test transaction::test::test_tx_mysql_commit_defer has been running for over 60 seconds

我试一下

zhuxiujia avatar Jul 20 '22 05:07 zhuxiujia

测试代码:

    use rbatis::db::{DBPool, DBPoolOptions};
    pub async fn init_db_mysql() -> Rbatis {
        let rb: Rbatis = Rbatis::new();
        let mut opts: DBPoolOptions = DBPoolOptions::new();
        rb.link_opt("mysql://root:[email protected]:3306/mysql", opts).await;
        rb
    }

    //示例-Rbatis使用事务,类似golang defer,守卫如果被回收则 释放事务
    #[tokio::test]
    pub async fn test_tx_mysql_commit_defer() {
        fast_log::init(fast_log::config::Config::new().console());
        let rb: Rbatis = init_db_mysql().await;
        forget_commit(&rb).await.unwrap();
    }

    pub async fn forget_commit(rb: &Rbatis) -> rbatis::core::Result<()> {
        // tx will be commit.when func end
        let mut tx = rb.acquire_begin().await?.defer_async(|mut tx| async move {
            if !tx.is_done() {
                tx.rollback().await;
                println!("tx rollback success!");
            } else {
                println!("don't need rollback!");
            }
        });
        let v = tx
            .exec("update biz_activity set names = '6' where id = 1;", vec![])
            .await?;
        //tx.commit().await;  //if commit, print 'don't need rollback!' ,if not,print 'tx rollback success!'
        return Ok(());
    }

log

running 1 test
2022-07-19 18:11:52.554779 INFO rbatis::plugin::log - [rbatis] [391895266325827584] Exec   ==> update biz_activity set names = '6' where id = 1;
                                                         [rbatis]                      Args   ==> []
2022-07-19 18:11:52.556121 ERROR rbatis::plugin::log - [rbatis] [391895266325827584] ReturnErr  <== error returned from database: 1146 (42S02): Table 'mysql.biz_activity' doesn't exist  src/plugin/log.rs:45

test transaction::test::test_tx_mysql_commit_defer has been running for over 60 seconds

经过测试,main函数,或者改成test fn(而不是async fn)的方式正常回滚。在tokio::test中好像会锁死

 #[test]
    pub fn test_tx_mysql_commit_defer() {
let rt = tokio::runtime::Builder::new_multi_thread()
            .enable_all()
            .build()
            .unwrap();
        rt.block_on(async move {
   ///rollback逻辑
   });
}

zhuxiujia avatar Jul 20 '22 06:07 zhuxiujia

v4 版本已更改为tokio::spawn方式

zhuxiujia avatar Aug 12 '22 12:08 zhuxiujia