1

不久前,我完全重新编码了我的应用程序,以便 MySQL 以 ACID 方式执行。

在所有功能的最顶层,我做这样的事情:

        try{
            $db->begin();
            dosomething($_SESSION['userid']);
            $db->commit();
        }catch(advException $e){
            $eCode = $e->getCode();
            $eMessage = $e->getMessage();
            # Success
            if ($eCode == 0){
                $db->commit();
            }else{
                $db->rollback();
            }
        }

在“dosomething”函数中,我向用户抛出了异常,例如:

throw new Exception('There was a problem.',1);

或者

throw new Exception('You have successfully done that!', 0);

这样我就可以控制程序的流程。如果出现问题,则回滚发生的所有事情,如果一切正常,则提交。一切都很好,但到目前为止我只遇到了一个缺陷。我添加了异常日志记录,以便我可以查看用户何时遇到问题。但问题是,如果记录错误的表是 InnoDB,那么它也包含在事务中,如果出现问题将回滚,因此不会存储错误。为了解决这个问题,我基本上只是创建了错误记录表 MyISAM,所以当回滚完成时,更改仍然存在。

现在我正在考虑其他一些我想避免在交易之外的内容,比如在我的应用程序中向管理员发送邮件以帮助提醒问题。

我有什么方法可以不在父事务中包含数据库插入吗?我在应用程序/数据库设计方面是否采取了错误的路线,还有其他方法可以解决这个问题吗?

谢谢,多米尼克

4

2 回答 2

3

成功时抛出异常并不是一个好主意。

在调用先前的回滚后,您必须执行数据库插入。

catch (Exception $e) {
  $db->rollback();
  Log::insert('Error: ' . $e->getMessage());
}

尝试使用 Logger 来控制您的程序。这是更灵活的方式。

于 2011-07-11T19:43:38.410 回答
0

使用返回码表示操作成功,使用 Exceptions 指定异常情况(如严重错误等)。至于您的具体问题,如果您选择使用回滚策略,我建议您使用单独的数据库进行日志记录。

于 2011-07-11T22:38:05.607 回答