ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
### 模型事务操作 * 前言 * 1\. Mysql数据库注意 * 2\. thinkPHP模型使用事务 # 前言 事务操作在复杂的数据库操作的时候尤为重要,特别是在操作多张表的时候,如果某一步骤出错了,就会导致有脏数据,会很危险,比如A表操作完需要再操作B表,如果A表操作成功,B表操作失败,那么A表的数据需要回滚,否则A表就会有脏数据。这个时候事务处理就派上用场了。 # 1\. Mysql数据库注意 使用事务处理的话,需要数据库引擎支持事务处理。比如`MySQL`的`MyISAM`不支持事务处理,需要使用`InnoDB`引擎。 使用`navcat`工具的可以在`设计表`中的`选项`找到`引擎`,修改为`InnoDB`即可: ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210102233620966.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3p5MTI4MTUzOTYyNg==,size_16,color_FFFFFF,t_70) > Tips: 每张数据表都需要单独修改`InnoDB`引擎。 # 2\. thinkPHP模型使用事务 官方文档介绍的是`Db`类操作数据库的事务处理,这里就不说了。这里介绍的是使用`模型`操作数据库如何做。 举个简单的例子: * 第一步,根据用户名、密码插入用户数据; * 第二步,修改刚新增用户的手机号为123; 若其中一步操作失败则全部回滚,此用户数据删除。 > 控制器层 ~~~php public function insert(){// 演示数据$data = ["username" => "zhangsan","password" => "12313212"];$res = (new UserBis())->insertData($data);if(!$res) {return show(0, "新增失败");}return show(1,"新增成功"); } ~~~ > Business层 ~~~php <?php namespace app\admin\business; use app\common\model\mysql\User as UserModel; use think\Exception;class User extends BaseBis {protected $model = null;public function __construct(){$this->model = new UserModel();}public function insertData($data){// 开启事务$this->model->startTrans();try {$uid = $this->add($data);if(!$uid){return $uid;}$user = $this->model->find($uid);$res = $user->save(["id"=>$uid,"phone_number"=>"123"]);if(!$res){throw new Exception("更新手机号失败");}// 提交事务$this->model->commit();}catch (Exception $e){// 事务回滚$this->model->rollback();return false;}return true;} } ~~~ > BaseBis层 ~~~php <?php namespace app\admin\business; use think\Exception; class BaseBis {protected $model;public function add($data){// 默认status字段赋值$data['status'] = config("status.mysql.table_normal");try {$res = $this->model->save($data);}catch (Exception $e){return 0;}// 返回idreturn $this->model->id;} } ~~~ 为了验证回滚结果,我把第二次的数据库操作的结果设置为`false`: ~~~php $res = $user->save(["id"=>$uid,"phone_number"=>"123"]); // 模拟操作出错的情况 $res = false; ~~~ 第1,2次正常处理,第3,4次修改为模拟出错的情况,第5次正常处理: ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210102235206252.png) 可以看到`id`为`9,10`的数据不存在,这就是回滚的效果,当第二次操作失败的时候第一次的操作也会回滚。