• 【PHP】thinkphp3.2.5


    线上一段代码

    try {
        $uModel = M('Users');
        $uModel->startTrans();
        $userInfo = $uModel->where(['user_id' => 3])->select();
        throw new Exception('操作失败');
    } catch (Exception $e) {
        $uModel->rollback();
        var_dump($e->getMessage());
    }
    

      

    提示信息:

    There is no active transaction
    FILE: /datas/www/fxk/ThinkPHP/Library/Think/Db/Driver.class.php(323)
    #0 /datas/www/fxk/ThinkPHP/Library/Think/Db/Driver.class.php(323): PDO->rollBack()
    #1 /datas/www/fxk/ThinkPHP/Library/Think/Model.class.php(1709): ThinkDbDriver->rollback()
    #2 /datas/www/fxk/Application/Cron/Controller/TestController.class.php(19): ThinkModel->rollback()
    #3 [internal function]: CronControllerTestController->run()
    #4 /datas/www/fxk/ThinkPHP/Mode/Cron/App.class.php(212): call_user_func_array(Array, Array)
    #5 /datas/www/fxk/ThinkPHP/Mode/Cron/App.class.php(99): ThinkApp::invokeAction('Test', 'run')
    #6 /datas/www/fxk/ThinkPHP/Mode/Cron/App.class.php(58): ThinkApp::exec()
    #7 /datas/www/fxk/ThinkPHP/Library/Think/Think.class.php(136): ThinkApp::run()
    #8 /datas/www/fxk/ThinkPHP/ThinkPHP.php(100): ThinkThink::start()
    #9 /datas/www/fxk/cron.php(11): require('/datas/www/fxk/...')
    

      

    查看代码Driver.class.php 323

    应该是$this->_linkID属性有问题,这个属性的定义是在initConnect方法,如下:

    protected function initConnect($master = true)
    {
        // 开启事物时用同一个连接进行操作
        if ($this->transPDO) {
            return $this->transPDO;
        }
    
        if (!empty($this->config['deploy']))
        // 采用分布式数据库
        {
            $this->_linkID = $this->multiConnect($master);
        } else
        // 默认单数据库
        if (!$this->_linkID) {
            $this->_linkID = $this->connect();
        }
    
    }
    

      

    如果存在 transPDO直接返回,这个属性是那里来的,请看(其实就是_linkID,用来判定是否在事务中,避免事务嵌套):

    public function startTrans()
    {
        $this->initConnect(true);
        if (!$this->_linkID) {
            return false;
        }
    
        //数据rollback 支持
        if (0 == $this->transTimes) {
            // 记录当前操作PDO
            $this->transPdO = $this->_linkID;
            $this->_linkID->beginTransaction();
            ThinkLog::record(date('H:i:s ') . 'begin;', 'mysql');
        }
        $this->transTimes++;
        return;
    }
    

      

    发现问题,开启事务时候赋值的是transPdo,而在initConnect里面判断是transPDO,这点很有问题,但是为什么会导致这个报错,返回到调试代码,我们把代码简化,去掉查询后,执行正常,那问题可能就在执行了select()

    在select中的query方法,调用了initConnect初始化,串联起来原因就出来了:开启事务的时候初始化了句柄存在transPdo,中间调用Select方法,判断的是transPDO发现不存在,于是重新生成了一个句柄,这个句柄是没开启事务的,然后抛出一场时事务回滚就提示上面的错误信息了

    得意时做事,失意时读书
  • 相关阅读:
    3delight and useBackground
    Maya 闪电
    jcCut1.1 在Maya里实现切割物体
    jcFeather 2.3.0 Demo
    javascript深度克隆的方法
    前端调用本地摄像头实现拍照(vue) Allen
    《暗时间》 读书笔记
    阅读笔记3流浪动物救助实践困境与路径优化
    阅读笔记1濒危动物网页的设计构思
    阅读笔记2电子宠物系统设计
  • 原文地址:https://www.cnblogs.com/lanse1993/p/12566309.html
Copyright © 2020-2023  润新知