From 12800468b1b9c72be8a28cf5a993c74a9cd1a8ed Mon Sep 17 00:00:00 2001 From: Billy Chan Date: Mon, 11 Oct 2021 23:00:24 +0800 Subject: [PATCH] Test nested transaction --- tests/transaction_tests.rs | 245 +++++++++++++++++++++++++++++++++++++ 1 file changed, 245 insertions(+) diff --git a/tests/transaction_tests.rs b/tests/transaction_tests.rs index 61d194c4..57739dde 100644 --- a/tests/transaction_tests.rs +++ b/tests/transaction_tests.rs @@ -101,3 +101,248 @@ fn _transaction_with_reference<'a>( Ok(()) }) } + +#[sea_orm_macros::test] +#[cfg(any( + feature = "sqlx-mysql", + feature = "sqlx-sqlite", + feature = "sqlx-postgres" +))] +pub async fn transaction_nested() { + let ctx = TestContext::new("transaction_nested_test").await; + + ctx.db + .transaction::<_, _, DbErr>(|txn| { + Box::pin(async move { + let _ = bakery::ActiveModel { + name: Set("SeaSide Bakery".to_owned()), + profit_margin: Set(10.4), + ..Default::default() + } + .save(txn) + .await?; + + let _ = bakery::ActiveModel { + name: Set("Top Bakery".to_owned()), + profit_margin: Set(15.0), + ..Default::default() + } + .save(txn) + .await?; + + // Try nested transaction committed + txn.transaction::<_, _, DbErr>(|txn| { + Box::pin(async move { + let _ = bakery::ActiveModel { + name: Set("Nested Bakery".to_owned()), + profit_margin: Set(88.88), + ..Default::default() + } + .save(txn) + .await?; + + let bakeries = Bakery::find() + .filter(bakery::Column::Name.contains("Bakery")) + .all(txn) + .await?; + + assert_eq!(bakeries.len(), 3); + + // Try nested-nested transaction rollbacked + let is_err = txn + .transaction::<_, _, DbErr>(|txn| { + Box::pin(async move { + let _ = bakery::ActiveModel { + name: Set("Rock n Roll Bakery".to_owned()), + profit_margin: Set(28.8), + ..Default::default() + } + .save(txn) + .await?; + + let bakeries = Bakery::find() + .filter(bakery::Column::Name.contains("Bakery")) + .all(txn) + .await?; + + assert_eq!(bakeries.len(), 4); + + if true { + Err(DbErr::Query("Force Rollback!".to_owned())) + } else { + Ok(()) + } + }) + }) + .await + .is_err(); + + assert!(is_err); + + let bakeries = Bakery::find() + .filter(bakery::Column::Name.contains("Bakery")) + .all(txn) + .await?; + + assert_eq!(bakeries.len(), 3); + + // Try nested-nested transaction committed + txn.transaction::<_, _, DbErr>(|txn| { + Box::pin(async move { + let _ = bakery::ActiveModel { + name: Set("Rock n Roll Bakery".to_owned()), + profit_margin: Set(28.8), + ..Default::default() + } + .save(txn) + .await?; + + let bakeries = Bakery::find() + .filter(bakery::Column::Name.contains("Bakery")) + .all(txn) + .await?; + + assert_eq!(bakeries.len(), 4); + + Ok(()) + }) + }) + .await + .unwrap(); + + let bakeries = Bakery::find() + .filter(bakery::Column::Name.contains("Bakery")) + .all(txn) + .await?; + + assert_eq!(bakeries.len(), 4); + + Ok(()) + }) + }) + .await + .unwrap(); + + // Try nested transaction rollbacked + let is_err = txn + .transaction::<_, _, DbErr>(|txn| { + Box::pin(async move { + let _ = bakery::ActiveModel { + name: Set("Rock n Roll Bakery".to_owned()), + profit_margin: Set(28.8), + ..Default::default() + } + .save(txn) + .await?; + + let bakeries = Bakery::find() + .filter(bakery::Column::Name.contains("Bakery")) + .all(txn) + .await?; + + assert_eq!(bakeries.len(), 5); + + // Try nested-nested transaction committed + txn.transaction::<_, _, DbErr>(|txn| { + Box::pin(async move { + let _ = bakery::ActiveModel { + name: Set("Rock n Roll Bakery".to_owned()), + profit_margin: Set(28.8), + ..Default::default() + } + .save(txn) + .await?; + + let bakeries = Bakery::find() + .filter(bakery::Column::Name.contains("Bakery")) + .all(txn) + .await?; + + assert_eq!(bakeries.len(), 6); + + Ok(()) + }) + }) + .await + .unwrap(); + + let bakeries = Bakery::find() + .filter(bakery::Column::Name.contains("Bakery")) + .all(txn) + .await?; + + assert_eq!(bakeries.len(), 6); + + // Try nested-nested transaction rollbacked + let is_err = txn + .transaction::<_, _, DbErr>(|txn| { + Box::pin(async move { + let _ = bakery::ActiveModel { + name: Set("Rock n Roll Bakery".to_owned()), + profit_margin: Set(28.8), + ..Default::default() + } + .save(txn) + .await?; + + let bakeries = Bakery::find() + .filter(bakery::Column::Name.contains("Bakery")) + .all(txn) + .await?; + + assert_eq!(bakeries.len(), 7); + + if true { + Err(DbErr::Query("Force Rollback!".to_owned())) + } else { + Ok(()) + } + }) + }) + .await + .is_err(); + + assert!(is_err); + + let bakeries = Bakery::find() + .filter(bakery::Column::Name.contains("Bakery")) + .all(txn) + .await?; + + assert_eq!(bakeries.len(), 6); + + if true { + Err(DbErr::Query("Force Rollback!".to_owned())) + } else { + Ok(()) + } + }) + }) + .await + .is_err(); + + assert!(is_err); + + let bakeries = Bakery::find() + .filter(bakery::Column::Name.contains("Bakery")) + .all(txn) + .await?; + + assert_eq!(bakeries.len(), 4); + + Ok(()) + }) + }) + .await + .unwrap(); + + let bakeries = Bakery::find() + .filter(bakery::Column::Name.contains("Bakery")) + .all(&ctx.db) + .await + .unwrap(); + + assert_eq!(bakeries.len(), 4); + + ctx.delete().await; +}