事务无法在 codeigniter 中回滚
Posted
技术标签:
【中文标题】事务无法在 codeigniter 中回滚【英文标题】:transaction can't rollback in codeigniter 【发布时间】:2018-02-09 19:04:10 【问题描述】:我正在处理事务,在提到的代码中我遇到了一些问题。我没有提交事务,但它向我的数据库中插入了数据。
$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";
我回滚了事务,并且再次将所有数据插入到我的数据库中。一定是什么问题?看不懂。
【问题讨论】:
【参考方案1】:不要使用$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】:答案已更新!
我必须告诉你,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();
【讨论】:
我想要回滚事务而不是做什么? 你对trans_off()
的使用是错误的。一旦运行,其他trans_
方法将不会执行。嗯......从技术上讲,他们执行,但一旦他们看到 trans_off()
已被调用,他们立即返回 FALSE。【参考方案3】:
据我所知,对于 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 将全部提交,或者如果任何事情失败,则所有回滚。
【讨论】:
【参考方案4】:为什么你要ROLLBACK
?是因为其他而不是虚假的trans_status
?如果是这样,请致电trans_rollback
在致电trans_complete
或trans_commit
。
听起来这对您的情况来说是最佳选择(对不正确的语法表示歉意):
trans_start
...
if ( some non-db problem ) trans_rollback
trans_complete
【讨论】:
【参考方案5】:这样做。 如果您想了解有关交易的更多信息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;
【讨论】:
【参考方案6】:您编写的代码与编写自动事务的方式几乎相同 - 只是不一样。我的建议?不要试图智取 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();
【讨论】:
以上是关于事务无法在 codeigniter 中回滚的主要内容,如果未能解决你的问题,请参考以下文章