ThinkPHP6项目基操(19.实战部分 Mysql模型事务操作)

前言

事务操作在复杂的数据库操作的时候尤为重要,特别是在操作多张表的时候,如果某一步骤出错了,就会导致有脏数据,会很危险,比如A表操作完需要再操作B表,如果A表操作成功,B表操作失败,那么A表的数据需要回滚,否则A表就会有脏数据。这个时候事务处理就派上用场了。

1. Mysql数据库注意

使用事务处理的话,需要数据库引擎支持事务处理。比如 MySQLMyISAM 不支持事务处理,需要使用 InnoDB 引擎。
使用navcat工具的可以在设计表中的选项找到引擎,修改为InnoDB即可:
在这里插入图片描述

Tips: 每张数据表都需要单独修改InnoDB引擎。

2. thinkPHP模型使用事务

官方文档介绍的是Db类操作数据库的事务处理,这里就不说了。这里介绍的是使用模型操作数据库如何做。

举个简单的例子:

  • 第一步,根据用户名、密码插入用户数据;
  • 第二步,修改刚新增用户的手机号为123;
    若其中一步操作失败则全部回滚,此用户数据删除。

控制器层

public function insert(){
    
    
	// 演示数据
    $data = [
        "username" => "zhangsan",
        "password" => "12313212"
    ];
    $res = (new UserBis())->insertData($data);
    if(!$res) {
    
    
        return show(0, "新增失败");
    }
    return show(1,"新增成功");
}

Business层

<?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
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;
        }
        // 返回id
        return $this->model->id;
    }
}

为了验证回滚结果,我把第二次的数据库操作的结果设置为false

$res = $user->save(["id"=>$uid,"phone_number"=>"123"]);
// 模拟操作出错的情况
$res = false;

第1,2次正常处理,第3,4次修改为模拟出错的情况,第5次正常处理:
在这里插入图片描述
可以看到id9,10的数据不存在,这就是回滚的效果,当第二次操作失败的时候第一次的操作也会回滚。

猜你喜欢

转载自blog.csdn.net/zy1281539626/article/details/112129778
今日推荐