LoginSignup
10
7

More than 5 years have passed since last update.

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

Last updated at Posted at 2018-05-09

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

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を見てみよう。

2018/10/27 追記

try〜finallyでtryの中でreturnを行ってもfinally句に記述されている処理はreturn前に実行されます。
ただし、finally句にreturnを記述するとfinally句からストレートに関数の呼び出し元に戻されるので、finally句の外に予め書いてた処理が行われません。

詳しくは↓の記事をご参照ください。
try-catch-finally句内のreturnについて - Qiita

さいごに

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

10
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
7