采用C语言实现的事务管理提供顺序执行和回滚的的能力,支持同步事务和异步事务的定义。
- 更完善的测试,极限测试
- 内存分配算法指定
- 文档支持
- 运行log
- demo
- 使用堆内存时,也提供内存泄漏检测。
- 多平台支持
- 根据定义action所依赖的struct,自动生成context
- 在action内可以注册回滚函数,后续执行失败后,可以执行之前注册的回滚函数
- 支持嵌套事务的定义,子事务执行成功,父事务失败,可以执行子事务的回滚动作
- 支持异步事务的定义,以及异步事务的回滚。
- 默认使用堆内存,可以选择使用静态内存,
- 当使用静态内存时,可以进行内存泄漏的检查
- Action 事务原子操作, 支持同步(SYNC_ACTION_DEF)异步(SYNC_ACTION_DEF)定义
- ActionContext Action依赖的上下文结构。
- Context 事务上下文,存储前后Action之间关联数据和回滚数据。
- TransAction 完整事务描述。
DEF_ACTION_CTXT(SimpleFailStruct){
char y;
};
SYNC_ACTION_DEF(SimpleFailAction, ACTION_CTXTs(ACTION_CTXT(SimpleFailStruct)))(Context* context) {
CAST_TO(SimpleFailStruct, s);
s->y = 2;
return ActionErr;
}使用CAST_TO把 Context转换 为Action所依赖的ActionContext
TRANS(trans,
ACTIONS(SimpleSyncAction
, SimpleAction2
, SimpleActionCheck
)
)
TransResult ret = syncExec(&trans);ACTIONS中顺序放之前定义的动作,框架会根据所有Action所依赖的ActionContext来确定
Context的大小。
void RollBackActionDemo(RollbackData* data){
if(data->len != sizeof(RollbackStruct)) return ;
RollbackStruct* s = (RollbackStruct*)data->mem;
}
NULL_CTXT_SYNC_ACTION_DEF(SimpleActionRollbackCheck)(Context* context) {
RollbackStruct s = {Expect_X};
RollbackData data = {&s, sizeof(s)};
addRollBackAction(&context->rollbackData, RollBackActionDemo, &data);
return ActionOk;
}异步 Action 定义
ASYN_ACTION_DEF(InitAction, ACTION_CTXTs(ACTION_CTXT(Simple1)))(Context *context) {
CAST_TO(Simple1, s);
s->x = 0;
return ActionOk;
}异步 Transaction 使用异步 Action
TRANS(trans,
ACTIONS(InitAction, SimpleAsynAction, sub1
)
)
Context *context;
TransResult ret = asynStart(&trans, &context);
ret = asynExec(context);需要保留上下文指针,在需要时继续 Transaction
使用CppUtest测试框架, https://github.com/cpputest/cpputest .框架自带一个Mock工具,虽然做不到Mockcpp那样无侵入的打桩static函数, 但对作为底层框架,不需要mock第三方函数的,使用起来也比较方便,尤其是换了诸多Mock工具对Mac支持都不太好。
SYNC_ACTION_DEF(SimpleActionCheck, ACTION_CTXTs(ACTION_CTXT(SimpleStruct)))(Context* context) {
CAST_TO(SimpleStruct, s);
mock().actualCall("SimpleActionCheck").withParameter("x", s->x);
return ActionOk;
}
TEST(TransactionTest, exec_one_action) {
mock().expectOneCall("SimpleActionCheck").ignoreOtherParameters();
TRANS(trans,
ACTIONS(SimpleSyncAction
, SimpleAction2
, SimpleActionCheck
)
)
TransResult ret = syncExec(&trans);
CHECK_EQUAL(ret, TransSucc);
mock().checkExpectations();
}