デッドロックの公式見解 http://www-3.ibm.com/cgi-bin/db2www/data/db2/udb/winos2unix/support/v8infocenter.d2w/report?target=mainFrame&fn=c0005271.htm For instance, if two processes read the table, and then update the table, process A might try to get an X lock on a row on which process B has an S lock, and vice versa. たとえば、2つのプロセスが表を読んで、そのあとに更新するとする。 BのプロセスがSロックをかけている行にAのプロセスがXロックをかけようし、 その逆も起きた場合。 To avoid such deadlocks, applications that access data with the intention of modifying it should use the FOR UPDATE OF clause when performing a select. This clause ensures that a U lock is imposed when process A attempts to read the data FOR UPDATE対応 更新を掛ける行に select for update with rsでUロックをかけたあとに update文のXロックをかける. こうすることでシステム全体で1度に1つのロジックがXロックをかけることになる。 デッドロックを回避することはできるが並行性は失われてしまう。 ダーティリード 可能な場合は with urをつけてロックなしで読み込むことでデッドロックを回避できる。 他のトランザクションが更新中の値も読んでしまうので WITH URをつけられるロジックは限られる。 自分のロジックがUPDATEしたレコードを再読み込みするときに WITH URをつけても問題ない。 ロックの種類 Uロックをかけることによって、 Xロックをかけるロジックがシステム全体で1つしか存在できないようにして デッドロックを防ぐことができる。 Table 21. Lock Type Compatibility State Being Requested\State of Held Resource none IN IS NS S IX SIX U X Z NW W none yes yes yes yes yes yes yes yes yes yes yes yes IN yes yes yes yes yes yes yes yes yes no yes yes IS yes yes yes yes yes yes yes yes no no no no NS yes yes yes yes yes no no yes no no yes no S yes yes yes yes yes no no yes no no no no IX yes yes yes no no yes no no no no no no SIX yes yes yes no no no no no no no no no U yes yes yes yes yes no no no no no no no X yes yes no no no no no no no no no no Z yes no no no no no no no no no no no NW yes yes no yes no no no no no no no yes W yes yes no no no no no no no no yes no リソースの参照の定義 まず、今回の失敗はリソースの参照を正しく定義していなかった。 このときDB2はRRで動作してしまう。 http://publib.boulder.ibm.com/infocenter/wasinfo/topic/com.ibm.websphere.base.doc/info/aes/javadoc/ae/com/ibm/websphere/rsadapter/JDBCConnectionSpec.html setTransactionIsolation public void setTransactionIsolation(int isolationLevel) Set the transaction isolation level. Any isolation level constant from the java.sql.Connection interface may be used, provided the backend supports it. If a value of TRANSACTION_NONE is specified, then the value specified in the res-ref will be used. If this value is also TRANSACTION_NONE or not specified, then the WebSphere default isolation level, specified in the DataStoreHelper, will be used. The WebSphere default values are: CloudScape: REPEATABLE READ DB2: REPEATABLE READ DB2/AS400: REPEATABLE READ Informix: REPEATABLE READ MSSQLServer/ConnectJDBC: REPEATABLE READ MSSQLServer/SequeLink: REPEATABLE READ Oracle: READ COMMITTED Sybase: REPEATABLE READ Unsupported databases: READ COMMITTED 03/07/09 11:51:43:878 JST] 1db2b2 ConnectionFac I J2CA0122I: リソース参照 jdbc/N00GNpn00z01d が見つかりませんでした。そのため、次のデフォルト値が使用されます: [Resource-ref settings] res-auth: 1 (APPLICATION) res-isolation-level: 0 (TRANSACTION_NONE) res-sharing-scope: true (SHAREABLE) res-resolution-control: 999 (undefined) [Other attributes] isCMP1_x: false (not CMP1.x) isJMS: false (not JMS) [03/07/09 11:52:05:852 JST] 1db2b2 WebGroup I SRVE0180I: [N00WPzeus2] [/ZEUS2_Web] 分離レベル RRモードと本来のCSモードでは同じDBなのにロック方式が大きく異なって動作する。 RRはコミットするまで参照した行はすべてロックされる。 CSは対象行をカーソルが通り過ぎればロックが外れる。 表にインデックスが張ってない場合に RRはselect文が表全体にSロックをかけてしまう。update文は表にSIXロックをかけてしまい。 デッドロックが発生し易くなる。 スキャン方式とロック http://publib.boulder.ibm.com/infocenter/db2help/topic/com.ibm.db2.doc/admin/c0009698.htm 日本語 http://www-3.ibm.com/cgi-bin/db2www/data/db2/udb/winos2unix/support/v8document.d2w/report?fn=r0005275.htm 英語 この表の意味がそもそもあいまい。RRのときは表にロックがかかることくらいはわかる。 Table 22. Lock Modes for Table Scans Access Method: Table scan with no predicates Isolation Level Read-only and ambiguous scans Cursored operation Searched update or delete Scan Where current of Scan or delete Update RR S/- U/- SIX/X X/- X/- RS IS/NS IX/U IX/X IX/X IX/X CS IS/NS IX/U IX/X IX/X IX/X UR IN/- IX/U IX/X IX/X IX/X Access Method: Table Scan with predicates RR S/- U/- SIX/X U/- SIX/X RS IS/NS IX/U IX/X IX/U IX/X CS IS/NS IX/U IX/X IX/U IX/X UR IN/- IX/U IX/X IX/U IX/X Table 23. Lock Modes for RID Index Scans Access Method: RID index scan with no predicates Access Method: Index scan with start and stop predicates only Access Method: RID index scan with a single qualifying row RR IS/S IX/S IX/X IX/X IX/X RS IS/NS IX/U IX/X IX/X IX/X CS IS/NS IX/U IX/X IX/X IX/X UR IN/- IX/U IX/X IX/X IX/X Access Method: Index Scan with index and other predicates (sargs, resids) only Table 24. Lock modes for index scans used for deferred data page access Access Method: RID index scan with no predicates Access Method: Deferred Data Page Access, after a RID index scan with no predicates Access Method: RID index scan with predicates (sargs, resids) Access Method: RID index scan with predicates (sargs, resids) RR IS/S IX/S - IX/S - RS IN/- IN/- - IN/- - CS IN/- IN/- - IN/- - UR IN/- IN/- - IN/- - Access Method: RID index scan with start and stop predicates only Access Method: Deferred data-page access after a RID index scan with start and stop predicates only Access Method: Deferred data-page Access, after a RID index scan with predicates RR IN/- IX/S IX/X IX/S IX/X RS IS/NS IX/U IX/X IX/U IX/X CS IS/NS IX/U IX/X IX/U IX/X UR IN/- IX/U IX/X IX/U IX/X Index scans used for deferred data page access データページに対するロックが延期される場合があり、2ステップのアクセスに分かれる。 Multiple Index Access 検索条件の列にインデックスが複数張ってあるとき。 List Prefetching データページのシーケンシャルな先読み。 このときは2つのステップに分けられ、それぞれでロックモードが違う。 1) RID index scan with predicates (sargs, resids) 2) Deferred data-page Access, after a RID index scan with predicates RIDとはレコードIDのこと。 インデックスがあるなしでのロックが変わる SELECT * FROM EMPLOYEE WHERE EMPNO = '000310'; 単純な Where文でも検索対象の対象の列にIndexが張ってあるかないかで ロック対象が全く異なる。 インデックスがあればオプティマイザはインデックスキャンを選び行ロック(row-level locking == IS)を行う。 インデックスがなければ表全体を検索しなければならず、このときは表ロック(table level lock == S)がかかる。 ロックのエスカレーション 行ロックに関するリソースが足りなくなると、DB2は行ロックをやめて表ロックにエスカレートする。 このときデッドロックは起きやすくなる。 maxlocks と locklist パラメータを増やして対応するか、ロックされる行を減らす。 デッドロック発生原因の特定 本番環境でデッドロックが発生した場合のデッドロック情報を取得する方法が不明。 オートノミックコンピューティング 結論 デッドロックが発生するとSQLExceptionがスローされて処理が異常終了する。 その原因となる排他制御はインデックスが張ってあるかどうか、行ロックのリソースが足りているかどうかなど 環境的な要因でも排他制御方式が変化する。 ZEUS2では業務にSQLを自由に発行させているので デッドロックが起きないロジックを業務に指針することはできない。 システム全体で表や行にアクセスする順番が統一できればデッドロックはなくなる。 Sロックがかかっている行にXロックをかけると発生するデッドロックは select for update with rsでUロックを対象行に掛けることによって回避できる。 しかし、そのUロックをかけたロジックはシステム全体で排他性制御されるロジックなので 並行性が失われパフォーマンスに影響がでる。 12月リリースに向けてプログラムや表は増えていくのでシステム全体でデッドロックが起きる可能性は増えていく。 デッドロックは起きるものとしてユーザによるリトライや、自動リトライロジックを組み込んで対応していく。 End of FILE.