PHPのDAOとDTOを使用した場合のロールバック処理に悩んでいます。
現在の構成は下記になっており、複数テーブルをまたがる依存性の高いトランザクション処理を実行した場合に、
どのようにしたら、シンプルに実装できますでしょうか?
<現在の構成>
・DAO、DTOはテーブルと1対1の構成で実装
・DAOのトリガーはビジネスロジック層で実装
・DBのオープンやトランザクションの実行はDAOのコンストラクタ、デコンストラクタで実装
<DB構成>
・aテーブル
・bテーブル
・cテーブル
<フォルダ構成>
プロジェクト
├DAO
│├a_dao.php
│├b_dao.php
│└c_dao.php
│
├DTO
│├a_dto.php
│├a_dto.php
│└a_dto.php
│
└LOGIC
└logic.php
やはり、ビジネスロジック層でDBコネクト及びトランザクション開始など実施したほうがよいでしょうか?
シンプルな実装方法がございましたら、ご教授くださいませ。
また、サンプルなどいただけましたら幸いでございます。
以上、よろしくお願いいたします。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答2件
0
ベストアンサー
スマホからざっくりとしたイメージで発言したので、語弊がありました。
フロントコントローラで実装するのではなく、アクションコントローラ側で実装を行います。
フロントコントローラは確かにルーティングおよびそれに関わる制御を司る役割です。
しかし、だからこそ、アクションコントローラを実行するぞ!、アクションコントローラの実行が終わったぞ!というタイミングを捕捉できるのもフロントコントローラです。
ご提示頂いたコードは、申し訳ありませんが、よく理解できませんでした。。。
(なぜDatabaseManagerを継承するようなクラスにビジネスロジック的なコードが??)
以下、1アクセス1トランザクションの一例です。
勿論、DIや要・不要を考えたら、無駄が発生する方法論でもありますが、無条件に簡素的に実装する方法となります。
色々はしょってますが、ニュアンスでご理解頂ければと・・・。
FrontBaseContrtoller
lang
1// なんやかんやrootingして対象actionを決定 2$actionClass = hoge; 3$actionName = fuga; 4try { 5 $actionClass->actionExecuting($actionName, $params); // パラメータとかも送ればいい 6 $actionClass->$actionName(); // rootingで決定されたアクセスへdispatch 7 $actionClass->actionSucceed($actionName, $params); // パラメータとかも送ればいい 8 9} catch(Exception $e) { 10 $actionClass->actionFailed($actionName, $params, $e); // パラメータとかも送ればいい 11}
ActionBaseController
lang
1class ActionBaseController { 2 public function actionExecuting($actionName, $params) { 3 } 4 5 public function actionSucceed($actionName, $params) { 6 } 7 8 public function actionFailed($actionName, $params, $e) { 9 } 10}
ActionController
lang
1class ActionController extends ActionBaseController { 2 public function actionExecuting($actionName, $params) { 3 parent::actionExecuting($actionName, $params); 4 // 設定ファイルなどから接続情報を取得し、DB接続して、Managerに登録さす 5 // $db = DbManager::create("DB1"); 6 } 7 8 public function actionSucceed($actionName, $params) { 9 parent::actionSucceed($actionName, $params); 10 // Managerが管理しているDBをすべてCommit 11 // DbManager::commitAll(); 12 } 13 14 public function actionFailed($actionName, $params, $e) { 15 parent::actionFailed($actionName, $params, $e); 16 // Managerが管理しているDBをすべてRollback 17 // DbManager::rollbackAll(); 18}
HogeActionController
lang
1class HogeActionController extends ActionController { 2 public function page1() { 3 $dto = // なんやかんやしたDTO 4 $dao1 = new TableDao1(); 5 $dao1->ins($dto); 6 $dao2 = new TableDao2(); 7 $dao2->ins($dto); 8 } 9}
DbAccessor
lang
1class DbAccessor { 2 private $_dbName; 3 4 public function __construct($dbName) { 5 $this->_dbName = $dbName; 6 } 7 8 public function insert($tableName, $entity) { 9 // $tableNameに$entityの値をプレースホルダーなどを利用してinsert 10 // $db = $DbManager::get($this->_dbName); 11 // $db->execute($query); 12 } 13 14 // 似たような実装で 15 public function select() { } 16 public function delete() { } 17 public function update() { } 18 public function execute() { } 19 20 // クエリの生成用にこんなメソッドがあったり 21 private function _createQuery() { } 22}
Dao1
lang
1class Table1Dao { 2 private $_db = new DbAccessor("DB1"); 3 4 public function ins($dto) { 5 // なんやかんやして、dtoからentityを生成 6 //$entity = new Table1Entity(); 7 8 $this->_db->insert("Table1", $entity); 9 } 10}
Dao2
lang
1class Table2Dao { 2 private $_db = new DbAccessor("DB1"); 3 4 public function ins($dto) { 5 // なんやかんやして、dtoからentityを生成 6 //$entity = new Table2Entity(); 7 8 $this->_db->insert("Table2", $entity); 9 } 10}
みたいな。
もうちょっと全体的に、まともに考える必要はありますが(雑すぎ)。
投稿2015/02/13 06:06
総合スコア130
0
フロントコントローラーなどによってDB接続できませんか?
DAOでは、どのDBを利用してアクセスするかを決定したうえでクエリ発行となると思います。(特に複数DBを利用する場合)
1アクセス1トランザクションとし、DAOでコミット、ロールバックは一切行わない、正常終了でコミット、例外発生でロールバック、ではダメでしょうか?
投稿2015/02/12 11:42
総合スコア130
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/02/13 07:40