[CakePHP] トランザクションを利用する

トランザクションを利用する…が、WEB系の場合は、ワンコールのトランザクションしか使えないので、複数のコール/Web APIにまたがる場合は、2フェーズコミットの方法を取る。まあ、チケット予約とかのように普通はダーティコミットの方式がパフォーマンスがよい。最後にチェックを入れて、整合性がなければ/既に予約済みだとかの場合は、エラーにしてしまう方式。社内業務の場合は、それほどパフォーマンスを必要としない or 途中の入力を破棄されるほうが痛い場合は、一時入力を保持する方式でセッションを作る。

ここはワンコールのトランザクションで。

■Model

Model/AppModel.php を書き換え

class AppModel extends Model {
	var $db ;
	function begin()
	{
	    $db = ConnectionManager::getDataSource($this->useDbConfig);
	    $db->begin($this);
	}
	   
	function commit()
	{
	    $db = ConnectionManager::getDataSource($this->useDbConfig);
	    $db->commit($this);
	}
	   
	function rollback()
	{
	    $db = ConnectionManager::getDataSource($this->useDbConfig);
	    $db->rollback($this);
	}
}

コネクションが Model に付属するので、$this->useDbConfig も Model 単位になってしまうという罠があるので、多人数で使う場合には考慮が必要。ただ、大抵の場合はワンコネクションで済ませてしまうので、わざわざマルチコネクションを利用してない場合には特に問題にならない。

CakePHPで複数テーブルに対するトランザクションを使う場合 – takami_hirokiの日記
http://d.hatena.ne.jp/takami_hiroki/20101109/p1

のように ADO.NET 風に Transaciton クラスを別に用意したほうがよいかも。

■Controller

ためしに、delete で commit/rollback してみる。

in Controller/TestController.php

	public function delete($id=null) {
		if (isset($this->params['url']['id'])) $id = $this->params['url']['id'];
		if ( $id != null ) {

			// トランザクション開始
		    $this->Test->begin();
    		// 処理を書く
			// $this->Test->read(null, $id);
			$this->Test->delete( $id );
			
			// コミット or ロールバック
    		$this->Test->rollback();
    		// $this->Test->commit();
   		}
		$this->set('Test',$this->Test->find('all'));
	}

コネクションが $this->Test に属しているのだが、$this->Store でも同じ。ConnectionManager::getDataSource($this->useDbConfig); なので。

■View

View は同じ

■結果

削除はロールバックされて、更新されない。

※クエリを見ると、「BEGIN」しかないけど大丈夫なのか?動作的には問題ない。

カテゴリー: CakePHP パーマリンク

[CakePHP] トランザクションを利用する への2件のフィードバック

  1. ミズノ野球 のコメント:

    playboy app ipad ミズノ野球 http://www.shoessretreat.info/

  2. さいふ のコメント:

    プラダ 店 さいふ http://www.bagsrational.com/

コメントは停止中です。