Crate transaction [−] [src]
Zero-cost transaction abstraction in Rust
This crate abstracts over transactions like STM, SQL transactions and so on. It is composable via combinators and does DI of transactions.
The basic idea is representing contracts of "this computation must be run"
as types. The trait Transaction
represents o sequence of computation that
must be run under a transaction. And transactions are composable
(sequencable) using then
, and_then
, or_else
, hence you can use it
like values wrapped in Result
.Since it represents computation to be run
in data, some types respond to control operators are provided: abort
for
?
, repeat
for for
, loop_fn
for loop
and branch
for (join point
of) if
and so on. As all the combinators have its own result type, no
dispatches are done at execution time thus it is zero-cost.
Another feature is it does DI of transaction. For database transaction, it means it injects DB connection from the context.
Examples
extern crate transaction; use self::transaction::prelude::*; // Since current rust doesn't support `impl Trait`, you need to make a // trait box // to return a trait value from a function. type BoxTx<'a, T> = Box<Transaction< Ctx = FooConnection, Item = T, Err =FooError> + 'a>; fn find_user<'a>(id: i64) -> BoxTx<'a, Option<User>> { // connection is inejected from the context with_ctx(move |cn: &mut FooConnection| { // .. }).boxed() } fn update_user<'a>(id: i64, name: &'a str) -> BoxTx<'a, Option<()>> { with_ctx(move |cn: &mut FooConnection| { // .. }).boxed() } fn update_find_user<'a>(id: i64, name: &'a str) -> BoxTx<'a, Option<User>> { update_user(id, name) // transaction can be composed using `and_then` .and_then(move |ret| match ret { None => // to return a leaf transaction, use `ok`, `err` or `result` ok(None) // to return from a branch (or, to match types at join // point), use `branch` API .branch() // use `first` in the first arm of the brnach .first(), Some(()) => find_user(id) .branch() // use `second` in the second arm of the brnach .second(), }) // finally, box it to return `BoxTx`. .boxed() }
Modules
prelude |
Structs
Abort |
The result of |
AndThen |
The result of |
Branch3Builder |
Branch3Builder |
Branch4Builder |
Branch4Builder |
BranchBuilder |
BranchBuilder |
Join |
The result of |
Join3 |
The result of |
Join4 |
The result of |
JoinAll |
The result of |
Lazy |
The result of |
LoopFn |
The result of |
Map |
The result of |
MapErr |
The result of |
OrElse |
The result of |
Recover |
The result of |
Repeat |
The result of |
Retry |
The result of |
Then |
The result of |
TryAbort | |
TryRecover |
The result of |
TxErr |
The result of |
TxOk |
The result of |
TxResult |
The result of |
WithCtx |
The result of |
Enums
Branch |
The result of |
Branch3 |
The result of |
Branch4 |
The result of |
Loop |
The status of a |
Traits
IntoTransaction |
types than can be converted into transaction |
Transaction |
An abstract transaction. Transactions sharing the same |
Functions
abort |
Take the previous successfull value of computation and abort the transaction. |
and_then | |
err |
make a error transaction value. |
join | |
join3 | |
join4 | |
join_all |
join a vec of transaction |
lazy |
lazy evaluated transaction value. Note that inner function can be called many times. |
loop_fn | |
map | |
map_err | |
ok |
make a successful transaction value. |
or_else | |
recover | |
repeat | |
result |
Take a result and make a leaf transaction value. |
retry | |
then | |
try_abort | |
try_recover | |
with_ctx |
Receive the context from the executing transaction and perform computation. |