WordpressとMySQLでトランザクション処理をする

一度の処理で複数のテーブルを更新する際、予期しないエラーが発生して中途半端にデータが更新されて放置されてしまう可能性がある。
それを避けるためにテーブルを更新する前にトランザクションを開始して、エラーが発生したらロールバック、処理が成功したらコミットしたいという事でネットの海から情報を拾ってソース書いた。

function hogehoge() {
    global $wpdb;

    // トランザクションを開始
    $wpdb->query("START TRANSACTION"); // BEGINでもOK

    // 処理対象のテーブルをロック(table_name1, table_name2は適宜変更)
    $wpdb->query("LOCK TABLES table_name1 WRITE, table_name2 WRITE");

    try{
        // 更新処理
        $result = update_hogehoge();

        // エラー起こしてないか確認
        if( is_wp_error( $result ) ){
            $wpdb->query('ROLLBACK'); // Rollback
            // 必要があればエラー処理
            return;
        }

        $wpdb->query('COMMIT'); // Commit

    }catch( Exception $e ){
        $wpdb->query('ROLLBACK'); // Rollback
        // エラー処理をもごもご

    }finally{
        // テーブルのロックを解除
        $wpdb->query('UNLOCK TABLES');
    }
}

注意事項

ストレージエンジン

MySQLのストレージエンジンがinnoDBじゃないとトランザクションが使えないので要注意。
ストレージエンジンの違いは↓を見てみるといいのかもしれない
http://shindolog.hatenablog.com/entry/2015/04/01/185703

テーブルロック

安意なテーブルロックはデッドロックを助長するのでご利用は計画的に。

テーブルロックのWRITEロックとREADロックの意味は↓を参考に
http://sawara.me/mysql/1918/

MySQLのテーブルロックはROLLBACKしてもUNLOCK TABLESをかけないと解除されないので注意。詳しくはMySQLのリファレンスを参照のこと。
テーブルロックとtry〜FinallyでUNLOCKはセットにしとくと安心。

try / catch / finallyについてはphp.netを見てみよう。

さいごに

至らぬ所がございましたらご助言、編集依頼いただけますと幸いです。

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.