Skip to main content
Version: 0.5.x

Transaction

A transaction is a group of SQL statements executed with ACID guarantee. There are two transaction APIs.

Within a Closure

The transaction will be committed if the closure returned Ok, rollbacked if returned Err. The 2nd and 3rd type parameters are the Ok and Err types respectively.

// <Fn, A, B> -> Result<A, B>
db.transaction::<_, (), DbErr>(|txn| {
Box::pin(async move {
bakery::ActiveModel {
name: Set("SeaSide Bakery".to_owned()),
profit_margin: Set(10.4),
..Default::default()
}
.save(txn)
.await?;

bakery::ActiveModel {
name: Set("Top Bakery".to_owned()),
profit_margin: Set(15.0),
..Default::default()
}
.save(txn)
.await?;

Ok(())
})
})
.await;

This is the preferred way for most cases. However, if you happen to run into an impossible lifetime while trying to capture a reference in the async block, then the following API is the solution.

begin & commit / rollback

begin the transaction followed by a commit or rollback. If txn goes out of scope, the transaction is automatically rollbacked.

let txn = db.begin().await?;

bakery::ActiveModel {
name: Set("SeaSide Bakery".to_owned()),
profit_margin: Set(10.4),
..Default::default()
}
.save(&txn)
.await?;

bakery::ActiveModel {
name: Set("Top Bakery".to_owned()),
profit_margin: Set(15.0),
..Default::default()
}
.save(&txn)
.await?;

txn.commit().await?;