2011-07-11 25 views
1

前一阵子我完全重新编码我的应用程序,这样的MySQL将在酸的方式进行。PHP和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,所以当回滚完成时,更改仍然存在。

现在,我想我想保持了交易的,像我的应用程序中发送邮件给管理员,帮助有问题的警告其他位。

有什么样的办法,我不包括父事务中的数据库插入?我是否在应用程序/数据库设计方面走了一条糟糕的路线,有没有其他办法可以处理?

谢谢,多米尼克

+2

你为什么在成功时抛出异常? –

+0

您可以始终拥有另一个DB句柄来执行日志记录,这会使日志部分独立于主句柄中的事务处理,但是您需要在日志记录系统中记录异常,所以您最终会记录您的日志记录,并且会令人厌恶。 –

+0

我的扩展异常类处理异常编号。如果异常代码是0,那么它是成功的。我认为这是退出代码并保持一致性的好方法。我猜如果我只是回来'你已经成功地做到了!';然后,我不需要检查在Exception catch中提交的eCode。 –

回答

3

这是不是一个好主意,抛出一个成功例外。

你要做的DB插入之前的回退被称为后。

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

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

0

使用返回代码成功运行,和异常指定特殊情况(如严重的错误,等等)。至于你的具体问题,如果你选择使用回滚策略,我建议有一个独立的日志数据库。

+0

所以你宁愿有一个单独的数据库登录,而不是有两个连接?我认为这个单独的连接理念听起来很酷。返回1中的代码,然后使用该号码从错误代码表中提取相应的消息? –