Zend框架抱怨"已经有一个活跃的交易"

cel*_*osa 2 mysql zend-framework transactions zend-db

我们正在使用zend_db_table,因为Zend Framework抱怨两个事务处于活动状态,所以我们遇到了一些问题:

[message:protected] => There is already an active transaction
[string:Exception:private] => 
[code:protected] => 0
[file:protected] => /var/www/vhosts/test.local/private/library/Zend/Db/Adapter/Pdo/Abstract.php
[line:protected] => 305
[trace:Exception:private] => Array
Run Code Online (Sandbox Code Playgroud)

这是Controller中的代码:

     public function convertAction()
{
    $this->setNoRender();

    // If the quote is a copy of a previous one, fetch all the datas
    $quoteId = Zend_Filter::filterStatic($this->getRequest()->getParam('qte_id'), 'int');
    $quoteTable = new Model_QuotesTable();
    $quoteRow = $quoteTable->findById($quoteId);
    if (count($quoteRow)) {
        $clonedId = $quoteRow->convertToJob();
        $this->flashMessageRedirect('Quotation successfully converted', '/jobs/edit/job_id/' . $clonedId);
    } else {
        $this->flashMessageRedirect('Unable to find the quote to be converted', '/quotes');
    }
}
Run Code Online (Sandbox Code Playgroud)

这是在QuotesTableRow中调用此函数,它扩展了zend_db_table_abstract:

    public function convertToJob()
{
    $db = $this->_getTable()->getAdapter();
    $db->beginTransaction();

    $jobsTable = new Model_JobsTable();

    try {

        /*
         * Update the status of the old row to match the $status passed into this function
         */
        $this->qte_status = "Accepted";
        $this->save();

        /*
         * Create new row with the same details as above
         */

        $newRow = $jobsTable->createRow();

        $newRow->job_title = $this->qte_title;
        $newRow->job_cus_id = $this->qte_cus_id;
        $newRow->job_enq_id = $this->qte_enq_id;
        $newRow->job_qte_id = $this->qte_id;
        $newRow->job_title = $this->qte_title;
        $newRow->job_description = $this->qte_description;
        $newRow->job_work_location_id = $this->qte_work_location_id;
        $newRow->job_work_category_id = $this->qte_work_category_id;
        $newRow->job_work_type_id = $this->qte_work_type_id;
        $newRow->job_cus_code = $this->qte_cus_code;
        $newRow->job_cus_name = $this->qte_cus_name;
        $newRow->job_wt_ref_code = $this->qte_wt_ref_code;
        $newRow->job_wt_description = $this->qte_wt_description;
        $newRow->job_wl_code = $this->qte_wl_code;
        $newRow->job_wl_description = $this->qte_wl_description;
        $newRow->job_wc_ref_code = $this->qte_wc_ref_code;
        $newRow->job_wc_description = $this->qte_wc_description;
        $newRow->job_qte_title = $this->qte_title;
        $newRow->job_datetime_created = date('Y-m-d H:i:s');

        $newRowId = $newRow->save();

        $db->commit();
        return $newRowId;
    } 
    catch (Exception $e) { 
        $db->rollback(); 

        echo('<pre>');
        print_r($e);
        echo('</pre>');
        exit();

        throw new Exception($e->getMessage());
        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

另外,它似乎与我们不在的模型有关,因为如果我们用与模型相关的mod()函数注释该行的脚本正在工作,而当我们评论其他保存时它返回相同的错误().

dre*_*010 6

这个错误是从MySQL返回的,而ZF只是告诉你错误信息.

您是否在同一个请求中启动了两个事务?这可以解释为什么你得到这个错误消息,或者你可能有一个在事务中间的中止连接,它没有回滚或自动提交.

您应该只为每个数据库连接启动一个事务.如果您需要两个模型在单个请求中拥有活动事务,那么您需要获得2个单独的数据库连接.

请参阅Bill Karwin关于此问题的这个(伟大的)答案.

您可以运行查询SHOW ENGINE InnoDB STATUS;以获取活动事务的列表.如果你有一个是开放的,你必须从PHP/ZF无活动事务,然后尝试关闭该交易,否则,你将不得不看着你的代码,看看两笔交易都在相同的请求开始.