2017-06-06 18:48:38 3605次浏览 1条回答 0 悬赏 10 金钱

有两个Exception 一个是\yii\base\Exception 一个是\yii\db\Exception,

这种捕获当程序出错的时候,应该都算是误操作,不论哪一种Exception 数据库都应该回滚,
但是这个Exception 应该捕获哪一个呢?

这些Exception的定义都不在一起,怎样确保抛出的异常一定被捕获

  • 回答于 2017-06-06 19:00 举报

    用父类\Exception捕获.

    16 条回复
    回复于 2017-06-06 22:39 回复

    无法确定的时候 就用这个是最保准的

    回复于 2017-06-07 10:31 回复

    我换成\Exception 能够捕获,但是没有回滚。
    我的代码是这样的 $transcation =Yii::$app->db->beginTranscation();
    try{

     $model1->save();
    throw new Exception();
     $model2->save();
    $transcation->commit();
    

    }catch(\Exception $e){
    $transcation->rollBack();
    }
    第一个model1保存了。。第二个没保存。但是第一个没回滚,是我用的方法不对吗?

    回复于 2017-06-07 12:00 回复

    save以后就无法回滚了,正确的操作应该先 validate() 全部pass以后再save

    回复于 2017-06-07 15:59 回复

    只要你在事务块内,使用save发生异常了也可以回滚。至于捕获哪个Exception,因为你捕获的范围是你操作的try块内代码,如果有想捕获的具体异常可以具体捕获,如果没有大可以直接捕获\Exception,不用担心什么,因为那段代码发生不了什么别的异常。注意查看你的表是什么引擎,必须是INNODB的。

    回复于 2017-06-08 14:15 回复

    恩恩,这个思路我正在用~(≧▽≦)/~

    回复于 2017-06-08 14:22 回复


    +--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
    | Engine | Support | Comment | Transactions | XA | Savepoints |
    +--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
    | FEDERATED | NO | Federated MySQL storage engine | NULL | NULL | NULL |
    | MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO |
    | MyISAM | YES | MyISAM storage engine | NO | NO | NO |
    | BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO |
    | CSV | YES | CSV storage engine | NO | NO | NO |
    | MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO |
    | ARCHIVE | YES | Archive storage engine | NO | NO | NO |
    | InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES |
    | PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO |
    +--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
    现在确实是innodb的。。但是第一个save()了,throw Exception之后,第一个没回滚。
    我出于这样考虑的原因是: $model1->save() 之后,$model2->save()之前,如果model2的rule验证失败。$model2就是empty的。 然后$model2->save()就不会写入了。。但是这个model1和$model2是 关联的 (父-子表),必须同时写入或者同时删除,有没有什么别的思路呢?

    回复于 2017-06-08 17:46 回复

    你现在要找的问题就是为什么没回滚,一定可以回滚,不要考虑别的了

    回复于 2017-06-08 18:00 回复

    可是现在model1中的数据已经插入了。。回滚的话必须删除这条数据,这里的回滚确实没起作用。就是说下边的
    $transcation->commit() 也没起作用的时候。 model1->save()已经保存了。 所以这次执行过后数据其实还是出错了

    回复于 2017-06-09 09:08 回复

    确认下引擎是INNODB吗?确认下代码是否有执行rollback.

    回复于 2017-06-09 12:01 回复

    确实是INNODB的。 因为这个是线上的库,数据库默认配置是MyISAM,我还手动把这俩表改成了INNODB引擎。回滚确实没执行,我实在想不出来是啥问题

    回复于 2017-06-09 12:55 回复

    show create table 看一下

    回复于 2017-06-09 16:03 回复


    KEY r_coustomer_id (coustomer_id)
    ) ENGINE=InnoDB AUTO_INCREMENT=71 DEFAULT CHARSET=utf8 ;
    我实在没招了。

    回复于 2017-06-20 10:45 回复

    你好,你的问题解决了吗,我也遇到了类似的问题,经过测试,如果是sql的异常会回滚,如果是手动抛出的异常,则不会回滚

    回复于 2017-07-04 15:30 回复

    确认是innodb的表,但整个db 是 MyISAM的,我怀疑是这个问题,还米有验证。我直接现在手动判断后再save。

    回复于 2017-07-04 15:30 回复

    如果是实在不行,就判断之后再save();我也没找到啥办法。

    回复于 2018-05-16 10:11 回复

    你好,这个问题当时怎么解决的

您需要登录后才可以回答。登录 | 立即注册
hzz
助理

hzz

注册时间:2017-03-09
最后登录:2019-06-10
在线时长:8小时32分
  • 粉丝1
  • 金钱110
  • 威望0
  • 积分190

热门问题