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