[Zend Framework][MySQL] Zend_Dbでトランザクション(MySQLi)
4月 14th, 2008 Posted in Zend Framework
Zend_Db_Adapter_Mysqliを使ってDBのトランザクションを制御する方法を書きます。とはいえ、インターフェースはZend_Db_Adapter_Abstractで定義されているので他のDBでも処理の書き方には変わりはないと思います。
MySQLの代表的なストレージエンジンで、InnoDBはトランザクションをサーポートしていますが、MyISAMはしていません。MyISAMでトランザクションを開始して、ロールバックを行った場合、特にException等が発生することはなくトランザクションの処理が無視(行の挿入や更新、削除等に対する取り消しがされません)されるだけですので注意してください。
トランザクションを開始するには、Zend_Db_AbstractのbeginTransaction()を、DBに対する処理を確定するにはcommit()関数を使います。また、何らかの処理が発生して、DBに対する処理をキャンセルしたい場合にはrollBack()を行います。
// Zend_Db_Tableを使っている場合は、 // $db = $tbl->getAdapter() でDBアダプターを取得しておきます // トランザクションの開始 $db->beginTransaction(); try { $db->query('insert ...'); $db->query('update ...'); $db->query('insert ...'); // Zend_Db_Table を使っている場合は、 // $tbl->insert($values); // $tbl->update($set, $where); // $tbl->insert($values); // コミット $db->commit(); } catch (Exception $e) { // 例外が発生したらロールバック $db->rollBack(); // 他のエラー処理 }
コミットとロールバックでDBに値がどのように変化するか調べます。
以下のようなテーブルの定義のときに、
mysql> show create table test\G *************************** 1. row *************************** Table: test Create Table: CREATE TABLE `test` ( `id` int(11) NOT NULL auto_increment, `title` varchar(50) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8
以下のように処理をしたとします。
$db->beginTransaction(); $db->query("insert into test('title') values('foo') "); $db->commit(); $db->beginTransaction(); $db->query("insert into test('title') values('bar') "); $db->rollBack(); $db->beginTransaction(); $db->query("insert into test('title') values('baz') "); $db->commit();
結果は、
mysql> select * from test; +----+-------+ | id | title | +----+-------+ | 1 | foo | | 3 | baz | +----+-------+
のように値が格納されます。AUTO_INCREMENTでロールバックすると、ロールバックした分はPRIMARY KEYが消費されます。
MyISAMで上記例のようにデータの挿入を行うとトランザクションは無視されるので、commit()を待たずにinsertが反映されます。
mysql> select * from test; +----+-------+ | id | title | +----+-------+ | 1 | foo | | 2 | bar | | 3 | baz | +----+-------+