READ UNCOMMITTED をむしろ使いたい状況?
私のサーバーシステムでは READ UNCOMMITTED をむしろ使用したいような状況が発生致しました。
私の考えは正しいでしょうか?
掲示板アプリのサーバーにて、掲示板に投稿したとして以下の処理が発生します。
- トランザクション
- トークテーブルに投稿を格納(insert)
- 掲示板テーブルの トータル投稿数更新(サブクエリではなくcount:=count+1で) と 最終投稿時間を更新(update)
- 掲示板テーブルから トータル投稿数 をセレクト(select)
- このトランザクション実行後、3番めのSQLで取得した投稿数が1000未満ならコミット
そうではないならロールバック(投稿失敗)
要するに、投稿格納後に投稿数上限の1000を超えていないかのチェックを行います。
一見、 SERIALIZABLE がいいように思えますが(もちろんそうなのですが)
処理性能のことも考えると、むしろここは一番最弱な READ UNCOMMITTED を使用したほうがいい気がしてきました。
READ UNCOMMITTED なら
2つの投稿トランザクションが同時に処理された場合、どちらかが先に2つめのSQLを実行した時点で、もう片方はトランザクション中に3番めのSQLにてそのコミットされていない値を取得して、
最大投稿数以上投稿してしまうことを防げると思ったからです。
この場合、上記の場合は
- 2つとも投稿処理が失敗する可能性(お互い、更新後にセレクトしたら)
→ そのぐらいべつにおk - 最新投稿時間がもう片方の投稿の時間になる可能性(セレクト順だけ逆転する)
→ とは言えど、同時に発生した処理のためその差は数ミリ秒程度なのでおk - 片方だけロールバック発生したらカウントがおかしくなることがある(現在インクリメント系 count=count+1なので)
→ 重要な不具合なのですがそもそもこのカラムをなくし、毎回取得時にカウントすることにする
が発生するかと思われますが、それは妥協とします。
このようにあえて READ UNCOMMITTED の弱点を利用するってのはやめるべきでしょうか?