事务无法在codeigniter中回滚

时间:2017-08-31 18:31:10

标签: php mysql codeigniter transactions codeigniter-3

我正在处理事务,在提到的代码中我遇到了一些问题。我没有提交事务,但是它将数据插入到我的数据库中。

$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";
}

我回滚了事务,并且所有数据都被插入到我的数据库中。一定是什么问题?我无法得到它。

6 个答案:

答案 0 :(得分: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();
}

答案 1 :(得分: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();
}

答案 2 :(得分: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_start 方法,它包含 trans_begin trans_complete 方法包含对 trans_status 的检查,因此会调用 trans_commit trans_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();

默认情况下,Codeigniter以严格模式运行所有事务,因此最后 trans_complete 将提交所有事务,或者如果所有回滚都失败。

答案 3 :(得分:2)

为什么你想要ROLLBACK?是因为其他而不是假trans_status?如果是,请在致电trans_rollbacktrans_complete之前致电trans_commit

听起来这对您的情况来说是最佳的(道歉语法不正确):

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

答案 4 :(得分: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;
}

答案 5 :(得分: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();