CI框架中的事务嵌套问题
2018-01-05 19:59
477 查看
我的环境 PHP5.6.25+ CI 2.2.0版本代码,该版本事务嵌套有问题。
问题1:事务嵌套,即:主方法中有 db->trans_begin(),子方法中也有db->trans_begin() ,如果子方法中也有事务,则如果回滚的话,会导致子方法之前的语句不受子方法中db->trans_rollback()的影响,所以可以考虑在主方法中开启事务,子方法不再开启事务,只需要在业务出错的时候,直接rollback后返回即可。
问题2:如果事务在两个model类中,需要考虑两个实例用的是同一个db实例,如果不是同一个实例,db->rollback() 也不会对之前开启的事务有影响,所以可能的话,需要将db传入进来,确认在同一个db实例上做事务操作才行,代码中的rollback才会生效。
CI不要嵌套事务,因为嵌套的事务,rollback仅对最近的事务起作用,看一下ci的源码:
所以我们做操作时,应该启动一个事务,只有一个trans_begin方法即可。
具体代码如下:
然后调用的dealer_extend_model类中的otherAdd方法如下:public function otherAdd($db_w)
{
$data = array(['mastername'=>'abc','actionid'=>20753,'url'=>'www.111.com'],
['mastername'=>'abcd','actionid'=>20753,'url'=>'www.sina.222.cn']);
$effectRows = $db_w->insert_batch('finance_log',$data);
var_dump($effectRows);
if ($effectRows > 0) {
//var_dump($this->db_w);
$db_w->trans_rollback();
return false;
}
}
问题1:事务嵌套,即:主方法中有 db->trans_begin(),子方法中也有db->trans_begin() ,如果子方法中也有事务,则如果回滚的话,会导致子方法之前的语句不受子方法中db->trans_rollback()的影响,所以可以考虑在主方法中开启事务,子方法不再开启事务,只需要在业务出错的时候,直接rollback后返回即可。
问题2:如果事务在两个model类中,需要考虑两个实例用的是同一个db实例,如果不是同一个实例,db->rollback() 也不会对之前开启的事务有影响,所以可能的话,需要将db传入进来,确认在同一个db实例上做事务操作才行,代码中的rollback才会生效。
CI不要嵌套事务,因为嵌套的事务,rollback仅对最近的事务起作用,看一下ci的源码:
function trans_begin($test_mode = FALSE) { if ( ! $this->trans_enabled) { return TRUE; } // When transactions are nested we only begin/commit/rollback the outermost ones if ($this->_trans_depth > 0) { return TRUE; } // Reset the transaction failure flag. // If the $test_mode flag is set to TRUE transactions will be rolled back // even if the queries produce a successful result. $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE; $this->simple_query('SET AUTOCOMMIT=0'); $this->simple_query('START TRANSACTION'); // can also be BEGIN or BEGIN WORK return TRUE; }这个方法中的_trans_depth实际上没有触发变化的地方。
所以我们做操作时,应该启动一个事务,只有一个trans_begin方法即可。
具体代码如下:
public function testTransaction() { $this->db_w->trans_begin(); $data = array(['mastername'=>'liuzhao113','actionid'=>20753,'url'=>'www.baidu.com'], ['mastername'=>'liuzhao113','actionid'=>20753,'url'=>'www.sina.com.cn']); $effectRows = $this->db_w->insert_batch('finance_log',$data); var_dump($effectRows); if (!$effectRows) { $this->db_w->trans_rollback(); } //$result = $this->otherAdd(); 使用自身model类中的方法起作用 $this->load->model(['dealer_extend_model']); $result = $this->dealer_extend_model->otherAdd();//使用其他model类默认的db_w,trans_rollback不起作用 $result = $this->dealer_extend_model->otherAdd($this->db_w);//使用同一个db_w起作用 if (!$result) { $this->db_w->trans_rollback(); var_dump($this->db_w); return; } if ($this->db_w->trans_status()) { //提交事务 $this->db_w->trans_commit(); } } public function otherAdd() { $data = array(['mastername'=>'liuzhaoaab','actionid'=>20753,'url'=>'www.111.com'], ['mastername'=>'liuzhaoaab','actionid'=>20753,'url'=>'www.sina.222.cn']); $effectRows = $this->db_w->insert_batch('finance_log',$data); var_dump($effectRows); if ($effectRows > 0) { //var_dump($this->db_w); $this->db_w->trans_rollback(); return false; } }
然后调用的dealer_extend_model类中的otherAdd方法如下:public function otherAdd($db_w)
{
$data = array(['mastername'=>'abc','actionid'=>20753,'url'=>'www.111.com'],
['mastername'=>'abcd','actionid'=>20753,'url'=>'www.sina.222.cn']);
$effectRows = $db_w->insert_batch('finance_log',$data);
var_dump($effectRows);
if ($effectRows > 0) {
//var_dump($this->db_w);
$db_w->trans_rollback();
return false;
}
}
相关文章推荐
- 登录页面嵌套在框架中问题
- Mac 环境下 基于CI框架 Apache 403 Forbidden 问题
- php CI框架的session问题
- CI框架的base_url localhost [::1]等问题
- CI框架css引入出现问题
- session过期后登录页面嵌套在框架中问题的解决方案
- CI框架在CLI下执行占用内存过大问题的解决方法
- CI框架去掉index.php以及解决No input file specified问题
- spring 中 Hibernate 事务和JDBC事务嵌套问题
- CI框架中base_url关于[::1]的问题
- “让CI框架支持service层”的那些问题
- 关于CI框架的url传值问题
- JavaEE框架——hibernate的使用(关于hibernate事务的必须开启的问题)
- CI 框架中将 URI 设置为 PATH_INFO 引发的问题
- CI框架2.x的验证码中所遇问题解决
- CI框架中使用URI类segment方法获取url中的中文参数的问题
- 关于CI框架 Session 的问题的 不可思议
- CodeIgniter框架——CI中视图路径问题
- bboss persistent事务框架针对BS TX泄露问题的处理
- 嵌套事务的问题