いろいろ準備中

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

コメントを投稿する