SOHOゆいちのサイト
postgresはトランザクションの多重実行ができないのですが、Zend_DbはPdoを利用したものなので、現在がトランザクション中かどうかを知るすべがありません。
実際のプログラムでは、個別の関数でトランザクションをbegin/commtするケースと、同じ関数を別のトランザクション内部から呼びたいケースがありました。
PHPのpostgres接続関数にはpg_transaction_statusがあって、重宝していたのですが、、、、そこで、Zend_Dbをオーバーライドして、begin/commit/rollBackの状態を管理できるようにしました。
※もっと楽な方法やPdoで対応可能な例があれば教えてください。 m(_ _)m
対処は単純でZend_Dbをオーバーライドしたクラスにbegin、commit、rollBackを実行するスタティックメソッドを用意しました。
前回複数の接続を管理できるようにしたクラスを利用します。
class Cshe_Db extends Zend_Db
{
static protected $canTransaction = array();static public function factory( $registName = ‘mainDb’)
{
try {
Zend_Loader::loadClass( ‘Zend_Registry’ );
if ( !Zend_Registry::isRegistered( $registName ) ) {
$appDatabaseConfig = Zend_Registry::get( ‘database_config’);// DB関連設定取得
$config = $appDatabaseConfig->toArray();
$adapterName = $config['database'][$registName]['type'];
unset( $config['database'][$registName]['type']);
$db = parent::factory( $adapterName, $config['database'][$registName]);Zend_Registry::set( $registName, $db);
} else {
$db = Zend_Registry::get( $registName);
}
return $db;
}
catch( Exception $e) {
throw $e;
}
}static public function beginTransaction($registName = ‘mainDb’)
{
try {$db = Ashe_Db::factory($registName);
$db->beginTransaction();// トランザクション開始を記録
self::$canTransaction[$registName] = false;
} catch (Exception $e) {
throw $e;
}
}static public function commit($registName = ‘mainDb’)
{
try {$db = Ashe_Db::factory($registName);
$db->commit();// トランザクション終了を記録
self::$canTransaction[$registName] = true;
} catch (Exception $e) {
throw $e;
}
}static public function rollBack($registName = ‘mainDb’)
{
try {$db = Ashe_Db::factory($registName);
$db->rollBack();// トランザクション開始を記録
self::$canTransaction[$registName] = true;
} catch (Exception $e) {
throw $e;
}
}
}
これで、トランザクションを処理するときにデータベースのAdapterクラスのインスタンスを直接利用せずに
Cshe_Db::beginTransaction();
Cshe_Db::commit();
Cshe_Db::rollBack();
を利用することで、以下のようにトランザクションを二重に実行されない(トランザクションがbeginされているときは何もせずに、beginされてないときはトランザクション処理する)関数が作れます。
function aaaa()
{
// トランザクションが未開始の場合開始
if ($isTransaction = Cshe_Db::isTransaction()) {
// トランザクション未開始
Cshe_Db::beginTransaction();
}
// いろいろな処理
// この関数でトランザクションが開始されている場合はコミット
if($isTransaction) {
Ashe_Db::commit();
}
}
www.bshe.org (created by itassist.info)