SQLのお話
ある一瞬のデータを取得したいと思ったらSELECTするだけですが、INSERTさせないようにしたいと思ったことはありませんか?
基本のロックシステムではINSERTをとめようと思ったらそれこそテーブルロックを行うしかありません。
情報テーブル
ユーザID
スレッドID
値
このようなテーブルがあるとします。何か情報があるとINSERTまたはUPDATEすることにより情報は更新されていきます。
ただこの情報をユーザ単位に洗い替えを行いたいというときにはどうすればいいのでしょうか?
Oracle:Lock Table "情報テーブル"
SQL Server: delete [dbo].[情報テーブル] with ( tablockx ) where ユーザID = 1
ただしこれではテーブル丸ごとロックされてしまう。
粒度としてはユーザ指定までだけに抑えたい。
ではどうするか?
情報テーブルロックテーブル
ユーザID
を作って
Oracle:SELECT * FROM "情報テーブルロックテーブル" where ユーザID = 1 FOR UPDATE
SQL Server: UPDATE delete [dbo].[情報テーブルロックテーブル] with ( UPDLOCK ) SET ユーザID = ユーザID where ユーザID = 1
という具合にそのテーブルにロックしてしまう。
これであれば、すくなくとも情報テーブルへの更新アクセスはシリアル化され、しかも業務的に制御可能になる。
#SQLレベルの実現方法がこんなに違うのに、SqlConnection, SqlCommandだけファクトリで取り出せたって仕方ないでしょ?
#Oracleは環境を持っていないのでなんとなくで書いているので間違っていたら指摘してください。
#ロックしている事実には代わりは無いので一瞬でも速くトランザクションは開放しましょう。
#当然シリアル化しているので同じユーザIDでのトランザクション流入量が多くなると悲しくなれます。