DB2で「SELECT ... FOR UPDATE」のロックを検証

採番用テーブルによってidの採番を行う場合、「SELECT ... FOR UPDATE」を使えばよい、というのがここ1年で覚えた知識のひとつ。ただ、あまり深くは理解していませんでした。

一番の疑問点は、「FOR UPDATE」という文字列の指す意味。ふつうに訳すと「更新のための」となり、照会は問題なく行えそうな気がしてきます。仮に照会が行えるとしたら、極めて近いタイミングのアクセスがが発生した場合、重複したidができる可能性があることになってしまいます。

また、ロックの種類はおおまかに共有ロック(照会可能、更新不可)と排他ロック(照会・更新とも不可)があるようです。FOR UPDATEで実際に排他ロックが獲得できているのか、そのあたりも気になります。

というわけで、現案件Java×DB2で調べてみることにしました。原始的な方法しか思い浮かばない自分にとっては、デバッグモードのあるEclipseは都合がよかったです。

検証

手順は以下です。

  1. トランザクションを有効にする
  2. 採番用テーブルからレコードを取得
  3. その直後にEclipseブレークポイントを設定
  4. アプリケーションの停止中に、CSESQL実行して検証
--SQL例
select VALUE from ID_GENERATOR where KEY = 'EMPLOYEE_ID' for update with rs

SELECTによる照会は、FOR UPDATEの有無で2通り検証しています。更新に関しては、ふつうにUPDATEでidの値を更新できるかどうかです。

DB2は「分離レベル」というものでロックの強度を指定できるようなので、その違いで検証しています。

分離レベル「UR
単純な照会
FOR UPDATEつき照会
更新
分離レベル「CS

※初期設定では、WITH句がない場合と同じ

単純な照会
FOR UPDATEつき照会
更新
分離レベル「RS」
単純な照会
FOR UPDATEつき照会×
更新×
分離レベル「RR
単純な照会
FOR UPDATEつき照会×
更新×
FOR UPDATE OF ...

「FOR UPDATE OF (カラム名)」という指定方法もあるようです。WITH句と共存できるかどうかは試してないのですが、とりあえず以下のSQLではどちらもロックがかかりませんでした。

select VALUE from ID_GENERATOR where KEY = 'EMPLOYEE_ID' for update of VALUE
select VALUE from ID_GENERATOR where KEY = 'EMPLOYEE_ID' for update of KEY
単純な照会
FOR UPDATEつき照会
更新
まとめ

DB2でテーブルによる採番を行う場合、以下のようにすればidの重複は起こらないといえます。

  • FOR UPDATE句を指定する
  • WITH句で分離レベルを「RS」か「RR」にする

※少しでも同時実行性を高めるために、「RR」よりも「RS」を指定するのがいいと思われます。

また言葉の意味についてですが、「FOR UPDATE」が修飾しているのはロックではなく、照会なのだと思います。「(後に)更新するための照会」であるがゆえに、ロックが必要、というわけですね。おそらく。

参考リンク
@IT:RDBMSアーキテクチャの深層(4)  OracleDB2、ロッキング・メカニズムはこれだけ違う
http://www.atmarkit.co.jp/fdb/rensai/rdbmsarc04/rdbmsarc04_1.html

DB2 Universal Database  分離レベル
http://publib.boulder.ibm.com/infocenter/db2luw/v8/index.jsp?topic=/com.ibm.db2.udb.doc/admin/c0004121.htm

DB2 UDB V8.1 デザイン・ガイド:ロック -基礎編- 
http://www-06.ibm.com/jp/domino01/mkt/dminfo.nsf/doc/000D73E3

浮浪プログラマの始末書:[DB] 排他制御
http://blog.livedoor.jp/froo/archives/50661135.html

转载于:https://www.cnblogs.com/aggavara/archive/2012/09/29/2708715.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值