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 | +—-+——-+