2012-08-02 55 views
2

我們使用Zend_Db_Table類,我們有,因爲Zend框架的一些問題抱怨兩筆交易活躍:Zend框架抱怨說,「已經有一個活躍的交易」

[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 

這是在控制器中的代碼:

 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'); 
    } 
} 

其回顧在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; 
    } 
} 

此外,它似乎與我們不在的模型有關,因爲如果我們使用與Model_JobsTable()相關的save()函數對該行進行註釋,該腳本正在工作,而在我們評論時它返回相同的錯誤另一個save()。

回答

6

這個錯誤是從MySQL返回,ZF只告訴你錯誤信息。

您是否在同一請求中啓動了兩個事務?這可以解釋爲什麼你得到這個錯誤消息,或者你可能有一箇中止連接,在事務中間,它沒有回滾或自動提交。

您應該只爲每個數據庫連接啓動一個事務。如果您需要兩個模型在單個請求中擁有活動事務,那麼您需要獲得2個獨立的數據庫連接。

查看Bill Karwin關於此問題的this (great) answer

您可以運行查詢SHOW ENGINE InnoDB STATUS;以獲取活動事務的列表。如果你有一個是開放的,並且你沒有來自PHP/ZF的活動事務,那麼請嘗試關閉該事務,否則你將不得不查看你的代碼並查看兩個事務是如何在同一個請求中開始的。

3

感謝您的回答,我們找到了解決方案。 問題是,我們使用了兩次save()函數;用insert()更改第一個save(),解決了問題:

public function convertToJob() 
{ 

    $db = $this->_getTable()->getAdapter(); 
    $db->beginTransaction(); 

    $jobsTable = new Model_JobsTable(); 

    try { 

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

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

     $newRowId = $jobsTable->insert($data); 

     /* 
     * Update the status of the old row to match the $status passed into this function 
     */ 

     $this->qte_status = "Accepted"; 
     $this->save(); 

     $db->commit(); 

     return $newRowId; 
    } 
    catch (Exception $e) { 
     throw new Exception($e->getMessage()); 
     return false; 
    } 
}