2017-08-31 89 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();