一度の処理で複数のテーブルを更新する際、予期しないエラーが発生して中途半端にデータが更新されて放置されてしまう可能性がある。
それを避けるためにテーブルを更新する前にトランザクションを開始して、エラーが発生したらロールバック、処理が成功したらコミットしたいという事でネットの海から情報を拾ってソース書いた。
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
#さいごに
至らぬ所がございましたらご助言、編集依頼いただけますと幸いです。