# 全自动事务
* * * * *
**简介**
在 数据 > 事务控制 章节咱们讲解了 如何通过闭包控制事务,但是实际项目开发中存在一些问题就是咱们必须提前将需要处理事务的代码刻意封装在闭包中且对于复杂的业务流程中多处验证返回上会不是很便利,若一套较为复杂的业务逻辑(比如多个分散的类或文件中都进行了需要数据操作)这种情况可能导致循环执行事务也可能导致没有循环但是执行了多次事务(实际上还是无法有效的保证数据完整性)。
下面咱们再来分享一种事务控制的方式
```
/**
* 自动封装事务
*/
function trans($parameter = [], $callback = null)
{
try {
Db::startTrans();
$backtrace = debug_backtrace(false, 2);
array_shift($backtrace);
$class = $backtrace[0]['class'];
$result = (new $class())->$callback($parameter);
Db::commit();
return $result;
} catch (Exception $ex) {
Db::rollback();
throw new Exception($ex->getMessage());
}
}
```
这个函数用于将顶层的方法自动嵌套到事务处理中。
**使用方式**
控制器中:
```
// 测试事务
public function tranEvent()
{
return trans($this->param, 'tranTest');
}
// 事务处理入口
public function tranTest($param = [])
{
dump($this->logicIndex->test($param));
}
```
业务逻辑中:
```
/**
* 测试操作
*/
public function test($data = [])
{
$this->modelArticle->setInfo(['name' => '666'], ['id' => 23]);
1/0;
//... 比如这里有多长很长的业务逻辑处理
//... 比如这里还执行了某文件里面的数据库操作
//... 比如这里执行了数据验证 比如 积分不足? 余额不足? 等操作
return [RESULT_SUCCESS, '操作成功'];
}
```
**解决的问题**
1.面向切面的事务控制,若初期开发中业务逻辑层没有考虑到事务控制,那么后面想加入事务机制只需要在控制器中加一个类似于事件的方法中转即可,业务层的代码基本上不需要改动。
2.避免了业务流程复杂时 循环执行事务及多个事务分散在各处无法保证多个事务都OK的情况。
3.清爽的代码将控制器中四处可见的 try catch 消灭掉。
4.有效提升了开发效率,开发者在编写业务逻辑时无需考虑数据完整性问题。
5.有效控制事务的同时也与OneBase目前返回跳转及提示机制完美兼容,不知不觉已经在所有的代码上自动加上了事务控制。
- 序言
- 基础
- 安装环境
- 安装演示
- 规范
- 目录
- 介绍
- 后台介绍
- 后台首页
- 会员管理
- 系统管理
- 系统设置与配置管理
- 菜单管理
- 系统回收站
- 服务管理
- 插件管理
- 文章管理
- 接口管理
- 优化维护
- SEO管理
- 数据库
- 文件清理
- 行为日志
- 执行记录
- 统计分析
- 接口介绍
- 接口文档
- 错误码设计
- Token介绍
- 前台介绍
- 架构
- 架构总览
- 生命周期
- 入口文件
- 模块设计
- 依赖注入
- 控制器架构
- 逻辑架构
- 验证架构
- 服务架构
- 模型架构
- 行为架构
- 插件架构
- 配置
- 配置介绍
- 配置加载
- 配置扩展
- 请求
- 请求信息
- 日志
- 后台行为日志
- 系统执行日志
- 框架日志
- 数据
- 数据库设计
- 数据字典
- 数据库操作
- 事务控制
- 混合操作
- 实战
- 控制器
- 逻辑与验证
- 视图与模型
- 插件研发
- 服务研发
- 接口研发
- 杂项
- 数据导入导出
- 二维码条形码
- 邮件发送
- 云存储服务
- 支付服务
- 短信服务
- 微信分享
- 生成海报
- 聊天室
- PJAX
- Demo
- Widget
- 附录
- 常量参考
- 配置参考
- 函数参考
- 进阶
- Redis
- 自动缓存
- 全自动缓存
- 索引
- 数据签名
- 全自动事务
- 队列