デッドロックの公式見解





デッドロックの公式見解

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