2011-08-29 18 views
3

私は、複数の測定単位をサポートするアプリケーションを作成しています。まれに、ユーザーが測定システムを変更したい場合は、アプリケーションのすべてのユニット列を正しい測定システムに合わせるために乗数を適用するクエリを実行する必要があります。この操作の何かがうまくいかない場合、すべてのデータが正常に維持されるようにするには、トランザクション内でクエリを実行する必要があります。CakePHPは複数のモデルでトランザクションをサポートしていますか?

複数のモデルをカバーするクエリを含むトランザクションをCakeで実行することは可能ですか?

私が今までに見つけたのはDataSource::begin/commit/rollback()ですが、これは単一のモデルに対するクエリのみをサポートしています。

+1

可能性のある複製http://stackoverflow.com/questions/3013347/transaction-management-with-multiple-models-using-single-transaction-commit-and-r – 8vius

+1

あなたは正しいです。基本的な質問と同じですが、適切な回答がないと判断して解決策がないようです。 –

+0

いくつかの関連モデルを保存するだけであれば、saveAll()メソッドを使うことができます – 8vius

答えて

4

はいです。私はトランザクションを簡単にするために私のアプリケーションモデルにこれを持っています。

function save1(){ 

    $saved = true; 
    $this->transaction(); 
    $saved = $saved && $this->save($data); 
    $saved = $saved && $this->save2($data); 


    if($saved){ 
     $this->transaction(true); 
     return $this->id; 
    } 

    $this->transaction(false); 
    return false; 
} 

ケーキは、ネストされたサポートしていません:あなたはまた、次のような、より複雑なことを行うことができます

$saved = true; 
$this->transaction(); 
$saved = $saved && $this->save($data); 
$saved = $saved && $this->SomeOtherModel->save($data2); 
$saved = $saved && $this->AnotherModel->save($data3); 

if($saved){ 
$this->transaction(true); 
    return $this->id; 
} 
$this->transaction(false); 
return false; 

https://github.com/infinitas/infinitas/blob/dev/Model/AppModel.php#L677

/** 
    * @brief wrapper for transactions 
    * 
    * Allow you to easily call transactions manually if you need to do saving 
    * of lots of data, or just nested relations etc. 
    * 
    * @code 
    * // start a transaction 
    * $this->transaction(); 
    * 
    * // rollback if things are wrong (undo) 
    * $this->transaction(false); 
    * 
    * // commit the sql if all is good 
    * $this->transaction(true); 
    * @endcode 
    * 
    * @access public 
    * 
    * @param mixed $action what the command should do 
    * 
    * @return see the methods for tranasactions in cakephp dbo 
    */ 
    public function transaction($action = null) { 
     $this->__dataSource = $this->getDataSource(); 
     $return = false; 
     if($action === null) { 
      $return = $this->__dataSource->begin($this); 
     } else if($action === true) { 
      $return = $this->__dataSource->commit($this); 
     } else if($action === false) { 
      $return = $this->__dataSource->rollback($this); 
     } 
     return $return; 
    } 

は、あなたがこのような何かを行うことができます取引をすることができますが、偽のものを並べ替えることができます

// this will use transactions if its called directly, but will allow a calling method to

// create and manage the transaction.

function save2($data){ 
    $saved = true; 
    $transaction = $this->transaction(); // will only be true if not already started 
    $saved = $saved && $this->save($data); 

    if($transaction){ // if it was started here, finish it 
     if($saved){ 
      $this->transaction(true); 
      return true; 
     } 

     $this->transaction(false); 
     return false; 
    } 

    return $saved; // return just the status so the other model will finish the transaction 
} 

だけ明確にすることが、あなたはClassRegistryような何かをやっている可能性が::のinit( 'SomeRandomModel') - > SAVE2()。トランザクションは現在のモデルまたは関連するモデルに限定されません。それはどんなモデルでもあります。

+0

うーん、あなたは正しいです。私は、DboSource :: begin()関数はDboからモデルとしてパラメータを必要とするため、いくつかのモデル固有のアクションを実行していると思っていましたが、明らかに実際には何も使用しません。 https://github.com/cakephp/cakephp/blob/1.3/cake/libs/model/datasources/dbo_source.php#L1799 –

+0

ほとんどのdboとビヘイビアのすべてのメソッドは、最初のパラメータとしてモデルを取ります。私は呼び出しを送信するメソッドがこれを行い、それが必要でない場合でもそれを取得すると思うでしょう。 – dogmatic69

+1

Cakeは実際に2.Xでネストされたトランザクションをサポートしています。 http://book.cakephp.org/2.0/ja/models/transactionsを参照してください。html#nested-transactions – jeffslofish

関連する問題