デッドロックの公式見解
デッドロックの公式見解
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.
2003/08/11-12
ugya@lycos.com