簡體   English   中英

Codeigniter交易

[英]Codeigniter Transactions

我正在使用Codeigniter交易

$this->db->trans_start();
$this->db->query('AN SQL QUERY...');
$this->db->trans_complete();

這工作正常,我trans_complete的問題是在trans_starttrans_complete我正在調用其他函數,這些函數處理數據庫,因此它們包含插入和更新以及一些刪除... ex:

$this->db->trans_start();
 $this->utils->insert_function($data);
 $this->utils->update_function2($test);
$this->db->trans_complete();

現在,如果執行這些函數並且發生一些錯誤,CodeIgniter將不會執行回滾。

處理此類問題的最佳方法是什么?

我想到的唯一解決方案是從這些函數返回錯誤,並在這些函數中添加( trans_stattrans_complete )如果它返回錯誤測試,則執行$this->db->trans_rollback

例如:

    $this->db->trans_start();
     $result = $this->utils->insert_function($data);
     if($result === false){
       $this->db->trans_rollback();
     }
    $this->db->trans_complete();

有沒有更好的方法呢?

更新1:

根據要求我正在調用的外部函數示例:

   // insert_function contains

    $rec = array(
        'numero' => $numero,
        'transaction_id' => $id,
        'debit' => $product_taxes['amount_without_taxes'],
        'date' => $data['date_transaction'],
    );
    $this->addExerciceAccountingRecords($rec);

  and addExerciceAccountingRecords contains

   function addExerciceAccountingRecords($records) {
    $this->db->insert('transactions_exercices', $records);
    }

使用transactions意味着支持數據庫安全地插入數據。 所以在Codeigniter中,我們Model中編寫每個與數據庫相關的函數而不是在Controller中。 在你的第二個代碼(不工作)中你有指向模型。( utils )。 這么簡單我敢肯定這不起作用。 因為它不是與模型和Controller並行的插入數據。 交易應該在模型中編碼( 我將在我的答案中寫入模型 )。


加載這些東西

  1. 數據庫庫
  2. 模型類
  3. URL幫助器
  4. 會議

假設

在您的代碼中,您使用$data$test作為數組。 所以我假設有兩個數組用於插入和更新數據。


你的數據集

$data = array(
   'title' => 'My title' ,
   'name' => 'My Name' ,
   'date' => 'My date'
);

$id = 007;
$test = array(
   'title' => $title,
   'name' => $name,
   'date' => $date
);

你的守則

$this->db->trans_start(); # Starting Transaction
$this->db->trans_strict(FALSE); # See Note 01. If you wish can remove as well 

$this->db->insert('table_name', $data); # Inserting data

# Updating data
$this->db->where('id', $id);
$this->db->update('table_name', $test); 

$this->db->trans_complete(); # Completing transaction

/*Optional*/

if ($this->db->trans_status() === FALSE) {
    # Something went wrong.
    $this->db->trans_rollback();
    return FALSE;
} 
else {
    # Everything is Perfect. 
    # Committing data to the database.
    $this->db->trans_commit();
    return TRUE;
}

筆記

  1. 默認情況下,Codeigniter以嚴格模式運行所有事務。 啟用嚴格模式時,如果您正在運行多組事務,則如果一個組失敗,則將回滾所有組。 如果禁用嚴格模式 ,則會獨立處理每個組, 這意味着一個組的故障不會影響任何其他組

我嘗試的更多的是一招,但它對我有用。

$this->db->trans_begin();
  $rst1=  $this->utils->insert_function($data);
  $rst2 =  $this->utils->update_function2($test);
if($this->db->trans_status() === FALSE || !isset($rst1) || !isset($rst2)){
   $this->db->trans_rollback();
}else{
   $this->db->trans_commit();
}

我懷疑問題與CodeIgniter處理對象的方式有關。

如果您轉到“創建庫”部分下的CI文檔:
http://ellislab.com/codeigniter/user-guide/general/creating_libraries.html
並查看與以下相關的部分:

$CI =& get_instance();
$CI->load->helper('url');
$CI->load->library('session');
$CI->config->item('base_url');

在主控制器中,您已使用自動加載或顯式加載類來加載/實例化數據庫類。

然后繼續打開事務,然后通過utils庫訪問數據庫函數。

但是,一旦在庫中使用$this-db ,您實際上正在訪問數據庫實例的另一個副本,而不是與您的事務關聯的副本。

要訪問同一實例,您需要使用get_instance()函數。

我認為應該解決你的問題。 將功能分成各種模塊的原始編碼風格非常出色。 您只需要了解這個額外的細節。

請嘗試確認回滾是否按預期工作。

代碼的內容包括以下控制器:

$this->db->trans_start();
$this->User_profile_m->create_new_user_profile();
$this->User_profile_m->create_new_user();
$this->db->trans_complete(); 

和一個簡單的模型user_profile_m來處理數據持久性:

function create_new_user()
{
    $data['user_name_usr'] = $this->input->post('user_name');
    $data['create_date_usr'] = NULL;

    $this->db->insert('user_usr', $data);  
}

function create_new_user_profile()
{
    $data['user_name_pro'] = $this->input->post('user_name');
    $data['user_description_pro'] = $this->input->post('user_description');
    $data['create_date_pro'] = NULL;

    $this->db->insert('user_profile_pro', $data);  
}

本質上,演示嘗試進行兩次插入(兩個表中的每一個都有一個)。 如果一個插入失敗,則另一個插入回滾。

我在CodeIgniter 2.1.3中構建了這個,我可以通過GitHub提供應用程序文件,或者將它們壓縮並發送給您。


注意:確保在運行手動事務時使用$this->db->trans_begin() ,而不是$this->db->trans_start()

$this -> db -> trans_begin(); 
$this -> utils -> insert_function ( $data );
$this -> utils -> update_function2 ( $test ); 
$this -> db -> trans_complete ();

如果使用MySql認證,請使用InnoDb格式

試試這個程序。 它真的對我有用:)

$this->db->trans_start();
   $this->utils->insert_function($data);
   $this->utils->update_function2($test);
if($this->db->trans_status() === FALSE){
   $this->db->trans_rollback();
}else{
   $this->db->trans_complete();
}

對於單個插入或更新記錄,您可以使用affected_rows函數

$this->db->insert('table_name', xss_clean($data));


//Check if there is a record affected
if($this->db->affected_rows() > 0)
              {
                  return true;
              }
              else
              { 
                  // if not succeeded
                  // check your last query 
                  die($this->db->last_query());
              }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM