• 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
  • 相关阅读:
    problems_mysql
    skills_mysql
    knowledge_mysql
    knowledge_impala
    oozie的常见错误
    problems_kafka
    problems_flume
    kafka在zookeeper默认使用/为根目录,将/更换为/kafka
    java学习笔记总略
    大公司怎么开发和部署前端代码——作者:张云龙[知乎兴趣转载]
  • 原文地址:https://www.cnblogs.com/aggavara/p/2708715.html
Copyright © 2020-2023  润新知