トランスアクション

Propelは列の削除や関係している列の削除のときなどatomicな命令を含むときに内部的にトランスアクションを使います。またPropelに必要なときにトランスアクションを指定しやることも可能です。

PDOは(データベースでサポートされているとしても)ネスト化したトランスアクションはサポートしていないため、一番外で指定されたトランスアクションのポイントがbegin/commit/rollbackポイントになります。内部的にはネスト化されたトランスアクションがすでに外のトランスアクションに含まれているため、別のトランスアクションを開始することに注意してください。

自分でトランスアクションポイントを設定するには、PDO接続オブジェクトを取得して、beginTransaction()commit()関数を呼ぶ必要があります。そして発生するかもしれない例外(Exception)をキャッチして、rollback()を呼ぶ必要があります。しかし普通はPDOExceptionがデータベースレベルでrollbackを呼ぶように命令するはずです(この動作に頼らないほうがいいと思いますが)。

  // Prpelから接続オブジェクトを取得
  $pdo = Propel::getConnection(MyPeer::DATABASE_NAME);
  $pdo->beginTransaction();
  
  try {

    SomeOtherUtil::doDeleteFromFilesystem($files);    
    $obj1->save($con);
    $obj2->save($con);  
    MyPeer::doDelete($obj3, $con);

    $pdo->commit();

  } catch (Exception $e) {
     $pdo->rollback();
     throw $e;
  }
}

この上の例ではsave()doDelete()関数が例外を投げて(削除が行われないということです)その後構文全体がrollbackされるということです。

この上の例では$conはsave()delete()関数に渡さているのにも注意してください。普通はこれをする必要は無いのですが、トランスアクションがPropel::getConnection()から接続オブジェクトが返されたときに始まっているため(PHP5は全てが参照なのを忘れないでください)なのに注意してください。しかしこうやって接続オブジェクトを渡すことで、外のセットからの接続を使っていることを忘れないためのいいやりかただと思います(ここの場合はトランスアクションが始まったということ)。また関数の中でのPropel::getConnection()を余計に呼んでしまうことを防ぎます。

制限

現在列のlockingへのサポートはありません(例えばSELECT blah FOR UPDATE)、これはPropel 2.0で修正されます。