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);

プログラムの流れをコントロールできるように。問題がある場合は、発生したすべてをロールバックし、問題がなければコミットします。それはすべて非常にうまく機能しましたが、これまでに遭遇した欠陥が1つだけあります. ユーザーが直面する問題がいつ発生するかを確認できるように、例外ログを追加しました。しかし、問題は、エラーを記録するテーブルが InnoDB の場合、それもトランザクションに含まれ、問題がある場合はロールバックされるため、エラーが保存されないことです。これを回避するために、基本的にエラー ログ テーブル MyISAM を作成しただけなので、ロールバックが完了しても変更は残っています。

今、トランザクションから除外したい他のビットについて考えています。たとえば、アプリケーション内で管理者にメールを送信して、問題を警告するのに役立ちます。

親トランザクション内にデータベース挿入を含めないようにする方法はありますか? アプリケーション/DB の設計に関して、私は間違った道をたどりましたか? これを処理できる他の方法はありますか?

ありがとう、ドミニク

4

2 に答える 2

3

成功時に例外をスローすることはお勧めできません。

前のロールバックが呼び出された後に DB 挿入を行う必要があります。

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

ロガーを使用してプログラムを制御してみてください。より柔軟な方法です。

于 2011-07-11T19:43:38.410 に答える