您的位置:首页 > 编程语言 > PHP开发

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的源码:

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;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息