2017-08-31 96 views
4

我正在處理交易,並在提到的代碼中遇到了一些問題。我沒有提交該事務,但它將數據插入到我的數據庫中。交易無法在codeingniter中回滾

$this->db->trans_begin(); 
$this->db->insert('tblorder',$data); 
$orderid=$this->db->insert_id(); 
foreach ($orderItemList as $orderItemList) { 
    $orderitem = array('orderid' =>$orderid ,'productid' =>$orderItemList->productid ,'amount' =>$orderItemList->amount); 
    $this->db->insert('tblorderitem',$orderitem); 
} 
$this->db->trans_complete(); 

if ($this->db->trans_status() == 1) { 
    $this->db->trans_rollback(); 
    return "true"; 
} else { 
    $this->db->trans_commit(); 
    return "false"; 
} 

我回滾事務,並再次將所有數據插入到我的數據庫中。什麼是這個問題?我無法得到它。

回答

2

答案已更新!

我必須告訴你,codeigniter的配置默認會自動提交所有事務。

如果出於任何原因要禁用此功能,您必須使用此行:

$this->db->trans_off();  

之前的

$this->db->begin(); 

說,所以當你使用

$this->db->trans_complete(); 

您需要提交或回滾,如下所示:

$result = $this->db->trans_complete(); 

if($result === true){ 
    $this->db->trans_commit(); 
}else{ 
    $this->db->trans_rollback(); 
} 

最後你想要的是:

$this->db->trans_off(); 

$this->db->query("insert this..."); 
$this->db->query("insert that..."); 

$result = $this->db->trans_complete(); 

if($result === true){ 
    $this->db->trans_commit(); 
}else{ 
    $this->db->trans_rollback(); 
} 
+0

我想回滾事務比會做什麼? –

+0

您錯誤地使用了'trans_off()'。一旦運行,其他任何'trans_'方法都不會執行。那麼......技術上他們執行,但一旦他們看到'trans_off()'被調用,他們立即返回FALSE。 – DFriend

2

至於我知道CI 3.0.1版本,你應該擔心的是唯一的東西放在哪裏$this->db->trans_start();$this->db->trans_complete();

所以對於像情況:

$this->db->trans_start(); 
//any code goes here 
$this->db->trans_complete(); 

如果出現問題,交易將回滾,或者將在致電$this->db->trans_complete();

因爲如果它包含trans_begintrans_start方法的引擎蓋下看。而trans_complete方法包含支票TRANS_STATUS,並相應地調用trans_committrans_rollback方法。

同樣適用於嵌套事務:

$this->db->trans_start(); 
//any code goes here 
$this->db->trans_start(); 
//any code goes here 
$this->db->trans_complete(); 
//any code goes here 
$this->db->trans_complete(); 

默認情況下笨運行在嚴格模式下的所有交易等最後trans_complete都將被提交,或者如果出現任何故障,所有回滾。

2

爲什麼是否要ROLLBACK?是否因爲其他比虛假trans_status?如果是這樣,請撥打trans_rollback,然後致電trans_completetrans_commit

這聽起來像這將是最適合你的情況(不正確的語法道歉):

trans_start 
... 
if (some non-db problem) trans_rollback 
trans_complete 
5

不要使用按$this->db->trans_complete();

documentation

$this->db->trans_begin(); 

$this->db->query('AN SQL QUERY...'); 
$this->db->query('ANOTHER QUERY...'); 
$this->db->query('AND YET ANOTHER QUERY...'); 

if ($this->db->trans_status() === FALSE) 
{ 
     $this->db->trans_rollback(); 
} 
else 
{ 
     $this->db->trans_commit(); 
} 
2

不喜歡這個。 如果您想了解更多關於交易Check My answer on another question。這有助於您清楚瞭解事務。

$this->db->trans_begin(); 

$this->db->insert('tblorder',$data); 
$orderid=$this->db->insert_id(); 

$orderitem = array(); 

foreach ($orderItemList as $orderItemList) 
{ 
    $orderitem[] = array('orderid' =>$orderid ,'productid' =>$orderItemList->productid ,'amount' =>$orderItemList->amount); 
} 

$this->db->insert_batch('tblorderitem', $orderitem); 

$this->db->trans_complete(); 

if ($this->db->trans_status() === FALSE) 
{ 
    $this->db->trans_rollback(); 
    return FALSE; 
} 
else 
{ 
    $this->db->trans_commit(); 
    return TRUE; 
} 
2

你寫的代碼幾乎是相同的方式自動交易被寫入 - 不僅沒有爲好。我的建議?不要試圖超越智能CodeIgniter,使用「自動」模式進行交易。然後,如果需要回滾,將爲您照顧。

我已經使用自動交易模式重做了您的代碼。我還從$orderItemList收集數據,因此可以使用批次插入,而不是在循環中重複調用db->insert

$this->db->trans_start(); 
$this->db->insert('tblorder', $data); 
$orderid = $this->db->insert_id(); 
foreach($orderItemList as $orderItem) 
{ 
    $orderedItems[] = [ 
     'orderid' => $orderid, 
     'productid' => $orderItem->productid, 
     'amount' => $orderItem->amount 
    ]; 
} 
if(isset($orderedItems)) 
{ 
    $this->db->insert_batch('tblorderitem', $orderedItems); 
} 
$this->db->trans_complete(); 
$this->db->trans_status();