
データベーストランザクション入門
データベースのトランザクションについて、深く考えるきっかけがありましたので、紹介します。
考えたきっかけはTwitter
ある日、Twitterを見ていたら、面白いタグが流れてきました。
長いこと、IT業界で働いていると、色々あるもんですね。
その中で、衝撃を受けたツイートがありました。
過去1番の衝撃コード。
function(){
…
try{
BeginTransaction()
…
commit()
} catch {
ログ記録テーブルへ書き込み()
commit()// 下行を実行するとログが
// 記録されなかったためコメントアウト。
// rollback()
}
}— うまかせぎ.com (@Umakasegi_com) May 30, 2019
ほんと衝撃過ぎて、言葉にならないというのは、このことだなと思いました・・・
企業のWebサイトなどでも、問い合わせフォームで利用されているのをよく見かけるようになりました。
衝撃のポイント
衝撃を受けたポイントは主に以下の3つ。
- catchの中でcommitしている
- 「下行(rollback)を実行するとログが記録されなかったためコメントアウト」とあるが、なんで?とならないのか?
- ログをデータベース(ログ記録テーブル)に保存している
データベース周りのトランザクションについて理解してないままプログラム組むと、こうなるかなと思うのと、レビューとかしないのかなと。
データベーストランザクションとは?
と、いうことで、いよいよ本題です。
トランザクションとは簡単にいえば「データベースに対して行われる1つ以上の更新処理」のこと。
トランザクションによってデータを更新する処理の確定や取り消しを管理できます。
トランザクションは預金の振込処理で考えると分かりやすいかと思います。
例えば口座Aから口座Bに1万円を振り込むとします。
- 口座Aの残高が1万円減る
- 口座Bの残高が1万円増える
という処理になるので、2つのデータを更新する必要があります。
この場合に、口座Aの残高を減らす処理はうまくいったけど、口座Bの残高を増やす処理でエラーが起きて、一部の処理だけがデータベースに反映されるとまずいですよね。
口座Aは1万円減ったのに、口座Bは1万円増えてないとか。
こうなってしまうとデータが不整合な状態になってしまうので、トランザクションの機能を使用して整合性を持たせます。
トランザクションを使用したコード
トランザクションの機能を使用する場合は以下のようにコードを実装します。
function hoge(){
try {
beginTransaction();
…
commit();
} catch (Exception $e) {
ログ出力
rollback();
}
}
ポイントは5つです。
try ~ catch
try ~ catch(トライキャッチ)は、エラーが起きた場合に検知する処理です。
tryで囲った中の処理でエラーが起きた場合は、catchの中の処理が実行されます。
こういう処理をすることで、口座Aの残高を減らす処理はうまくいったけど、口座Bの残高を増やす処理でエラーが起きて、みたいな時にデータの不整合を防ぎます。
詳細は以下に記載します。
beginTransaction
最初にトランザクションを開始します。
一連の処理を開始する時にこの処理を実行します。
commit
commit(コミット)はトランザクションを確定させる処理です。
振込の例だと、口座Aの残高を1万円を減らすこと、口座Bの残高を1万円増やすこと、の双方の処理が正常に完了した場合にのみ、コミットを実行します。
一度コミットした結果は元に戻すことはできないので注意が必要です。
rollback
rollback(ロールバック)はトランザクションを取り消す処理です。
ロールバックした場合、データベースはトランザクション開始前の状態に戻ります。
口座Aの残高を減らす処理はうまくいったけど、口座Bの残高を増やす処理でエラーが起きて、みたいな時は、ロールバックすることで最初の状態に戻ります。
このロールバックをすることで、口座Aだけ残高が減って、というデータの不整合を防ぐことができます。
ログ出力
今回のTwitterの例だと、データベースへログを書き込むようになっていましたが、僕的にはデータベースに書き込むことは、あまりおすすめしません。
今回のTwitterの例のように、更新したデータはロールバックして元に戻したいけど、ログだけは書き込みたいといった、書き込むデータごとに制御する必要が出てきてしまうからです。
何かしらエラーが起きたのであれば、データは全てロールバックして元に戻す、というのが理想です。
ログはデータベースではなく、ファイルに出力するべきだと思います。
僕なりのIT業界クソ現場オブザイヤー
最後に、本題とはちょっとずれますが、僕なりの「IT業界クソ現場オブザイヤー」も書きたいと思います。
レビュー指摘率
これはTwitterのフォロワーさんが書いていて、すごく共感したのですが、レビューを行う時に指摘率なるものが存在します。
例えば、5ページの設計書をレビューしたら、レビュー指摘は5件挙げないといけないとか。
5件より少なくても多くても、難癖付けられます。笑
少ない時は、指摘できてないけど大丈夫?
多い時は、指摘多いけど大丈夫?
指摘が多いのは問題ですが、少ない時は、なんとか指摘しようと直接設計には関係ない余白や文章の書き方で指摘を受けたりとか・・・
指摘率よりも指摘の内容が大事なのではないかな。
お客さんの鶴の一声で全て決まる時がある
お客さんの課題解決などのためにシステム開発をしているので、まあそうなんですが、こちらの意見が全然受け入れてもらえないということがありました。
その時の案件は、ゴールデンウィークがつぶれました。
提案しても全てひっくり返される時の虚しさといったら切なくなります。
と、書いてみましたが、今思うと良い思い出だったなと思います。笑
データベースのトランザクションは非常に大事なので、参考にしてみてください。
▼ 業務効率化代行サービス「カワリニ」
「業務効率化って簡単に言うけど、なかなか実現できない。」
そんな状況にいるのなら、お気軽にご相談ください。あなたの代わりに、業務効率化を担当します。
IT全般はお任せ。
プログラミングメインに活動中。
Java、PHP、C#、SQL、HTML、CSSやWordPressなどプログラミングから、情シスなど奮闘中。
最近の趣味はGAS。
競馬が好き。そしてスポーツ、読書、食べること、スイーツ好き。
好きなことでサービスやアプリを作りたい。
コメント ( 0 )
トラックバックは利用できません。
この記事へのコメントはありません。