2 个不稳定版本
使用旧的 Rust 2015
0.2.1 | 2017年6月23日 |
---|---|
0.2.0 |
|
0.1.0 | 2017年6月6日 |
#2001 在 Rust 模式
在 2 个 crate 中使用
36KB
1K SLoC
Transaction
一个零成本的交易抽象库。此 crate 提供了抽象和组合事务的方式。组合计算是在事务下运行的。不仅可以在事务下组合运行,它还 要求 计算是组合并在事务下运行的。
要运行事务,请使用类似 transaction-stm
或 transaction-diesel
的 crate
lib.rs
:
Rust 中的零成本事务抽象
此 crate 抽象了类似 STM、SQL 事务等事务。它可以通过组合子进行组合,并执行事务的依赖注入。
基本思想是将“必须运行此计算”的契约表示为类型。trait Transaction
表示必须在事务下运行的计算序列。事务可以使用 then
、and_then
、or_else
等方式组合(序列化),因此可以像使用包装在 Result
中的值一样使用它。由于它表示在数据中运行的计算,因此提供了一些响应控制运算符的类型:用于 ?
的 abort
,用于 for
的 repeat
,用于 loop
的 loop_fn
,用于 (join point of) if
的 branch
等。由于所有组合子都有自己的结果类型,因此在执行时不会进行调度,因此它是零成本的。
另一个特点是它执行事务的依赖注入。对于数据库事务,这意味着它从上下文中注入数据库连接。
示例
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| {
// ..
# let _ = (id, cn);
# unimplemented!()
}).boxed()
}
fn update_user<'a>(id: i64, name: &'a str) -> BoxTx<'a, Option<()>> {
with_ctx(move |cn: &mut FooConnection| {
// ..
# let _ = (id, cn, name);
# unimplemented!()
}).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()
}