2011-07-11 50 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中的代碼,然後使用該號碼從錯誤代碼表中提取相應的消息? –