クラスタリング検証 続報3

暗黙的にSelect for Update(排他ロック)を行うためには,jbosscmp-jdbc.xml要素の子要素として,trueと書くだけ.そうするとCMP Entity Beanオブジェクトに対する排他制御を行う場合と同じことができるというのを確認した.

暗黙的排他ロックを使わないと,シングルノードレベルではオブジェクトをロックすることによるトランザクション同時実行制御が働くけど,クラスタを行っている場合には不完全.

例えば,10スレッドがほぼ同時に同じCMP Entity Beanにアクセスしよとしてきている場合,ノードが2つだと5スレッドずつそれぞれのノードに割り振られることになる.そのそれぞれの5スレッドに対しては各ノードでオブジェクトのロックによる排他制御が行われてある瞬間に実行中となるスレッドを1つに限定することはできるけど,ノードが2つだとそれぞれのノード内で1つずつスレッドが実行されるので,結局2スレッドが同時にそれぞれのノードのCMP Entity Beanオブジェクトにアクセスし,そこから同時にRDBMSへアクセスされてしまう.

それを防ぐための暗黙的Select for Update.これによって複数のCMP Entity Beanオブジェクトが同時にあるテーブルのレコードへアクセスしようとしても,RDBMSのロック機構によって同時にアクセスできるCMP Entity Beanは一つに限られる.

共有ロックを伴うSerializableを使うという案は使わないほうがいい.例えば,行アをトランザクションAがSelectして共有ロックをかける,すぐ次に同じ行アをトランザクションBがSelectして共有ロックをかける,するとこの次にABからUpdateがかかるとデッドロックが成立してしまう.

暗黙的Select for Updateだと少なくとも1つの行に対しての更新ならデッドロックが発生しない.どうせCMP Entity Beanのオブジェクトに対して排他制御を行おうとしていたんだから,結果的には目的達成というわけでこれで良い.

ところでRDBMSの世界ではマルチバージョニングという機構によってロックに寄らない同時実行制御を行う実装があるわけだけど,J2EEサーバの世界はロックによる同時実行制御だけなんだよね.J2EEサーバもマルチバージョニングを実装,という案はどうなんだろう.思いつきだけど.