CI框架中的事务嵌套问题

我的环境 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;
        }
    }


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值