どうも、リモートワークでエンジニアをしているなおや(naoya2_2)です。
今回は備忘録的な記事になるのですが、仕事でバッチ処理に含まれるDB更新をトランザクション処理に切り替える必要があったのでやり方をまとめておきます。
SQLでトランザクション処理をする必要がある方は参考にしてください。
目次
トランザクション処理とは「複数の処理をひとつにまとめる」こと
トランザクション処理とはなんだ?ということですが、簡単に言うと「複数の処理をひとつにまとめる」ことです。
例えば『A → B』という順番に本来処理が進むものを、AとBの両方が問題なく(エラーなく)実行可能な場合だけ同時に実行することをトランザクション処理といいます。
“Aの処理は成功したけどBの処理は失敗しました”という場合にはAの処理も実行されずロールバックされることになります。
例えばお金の送金などに使われる処理
身近なものだと、お金の送金などにトランザクション処理が用いられています。
『A君 → B君にお金を送金する』パターンを例に考えてみましょう。
お金を送金する場合、ざっくり2つの処理が行われますね。
- A君の口座から送金分の残高を減らす処理
- B君の口座の残高を増やす処理
この2つです。
仮にここでトランザクション処理が行われず、A君の送金処理だけ成功してB君の受け取り処理が失敗するとどうなるでしょうか?
そう、A君の残高は減るものの、B君の残高は増えずお金がどこかに消えてしまうのです。これはやばいですよね。
こうならないようにトランザクション処理を行い、送金処理も受け取り処理も問題なく実行されることが保証された上で同時に2つの処理を実行します。
MySQLでトランザクション処理を実行する書き方
トランザクション処理をMySQLで行う方法ですがとてもシンプルです。複数の実行したい処理を”START TRANSACTION”(または”BEGIN”)と”COMMIT”(またはROLLBACK)で挟み込むだけ。
例えば、
1 2 3 4 | START TRANSACTION; 1つ目の処理; 2つ目の処理; COMMIT; |
こんな感じ。
これで、1つ目の処理と2つ目の処理がエラーなく完了する場合のみコミットされます。もしどちらかにエラーがあればコミットされず、勝手にロールバックされます。
実例でも見てみましょうか。
こんなテーブルがあるとします。
memoカラムにある「APPLE」を「ORANGE」に変更し、かつ「BANANA」も「ORANGE」に変更させるとしましょうか。
1 2 | UPDATE test_table SET memo = "ORANGE" WHERE memo = "APPLE"; UPDATE test_table SET memo = "ORANGE" WHERE memo = "BANANA"; |
これを実行した場合、普通に両方ともエラーなく変更されます。
でも、もし何かエラーが発生する要素があったら?
一旦テーブルを最初の状態に戻し、2つ目の更新処理の構文で敢えてエラーを発生させてみましょう。
1 2 | UPDATE test_table SET memo = "ORANGE" WHERE memo = "APPLE"; UPDATE test_table SET memo = "ORANGE" WHERE memooo = "BANANA"; |
こうすると、1つ目の実行だけエラーなく完了し更新され、2つ目の実行はエラーで弾かれます。
1つ目だけ「ORANGE」に更新されていますよね。
でも、両方の更新が成功するときだけ実行したい場合にトランザクション処理を使います。
また、テーブルをもとに戻し、以下のSQLを発行してみます。2つ目はエラーにします。
1 2 3 4 | START TRANSACTION; UPDATE test_table SET memo = "ORANGE" WHERE memo = "APPLE"; UPDATE test_table SET memo = "ORANGE" WHERE memooo = "BANANA"; COMMIT; |
すると、
1つ目の処理も行われず、更新されていません。
で、エラーを解消させて以下SQLを実行。
1 2 3 4 | START TRANSACTION; UPDATE test_table SET memo = "ORANGE" WHERE memo = "APPLE"; UPDATE test_table SET memo = "ORANGE" WHERE memo = "BANANA"; COMMIT; |
すると、
両方とも実行され「ORANGE」に更新されました。
このように、一連の処理が全て完了する場合だけまとめて実行するのがトランザクション処理です。
“START TRANSACTION”と”COMMIT”はセットで使う
トランザクション処理を行う場合”START TRANSACTION”(またはBEGIN)と”COMMIT”(またはROLLBACK)はセットで使いましょう。
“START TRANSACTION”を実行した場合はその後の処理は基本的に自動コミットされないので、”COMMIT”か”ROLLBACK”で処理を指定します。
- COMMIT:処理を実行、コミットする
- ROLLBACK:処理を実行しないでもとに戻す