30.10. 楽観的ロッキング
JBoss には、エンティティ bean の 楽観ロッキングに対するサポートがあります。楽観ロッキングによって、同じエンティティ bean の複数のインスタンスを同時にアクティブにすることができます。楽観ロッキングポリシー選択に基づいて一貫性を強化します。楽観ロッキングポリシー選択では、修正されたデータのデータベースへのコミット時間の書き込みに使用するフィールドセットを定義します。楽観ローディングの一貫性チェックでは、選択されたフィールドセットの値が、現行のトランザクションを開始した時点で存在していたデータベース内の値と同じであるということを表明します。これは、値のアサーションを含む
select for UPDATE WHERE ...
ステートメントを使用して行われます。
楽観ロッキングポリシー選択は、
jbosscmp-jdbc.xml
記述子の optimistic-locking
要素を使用して指定します。optimistic-locking
要素のコンテンツモデルを次に示し、その後に各要素の説明をします。
図30.14 jbosscmp-jdbc optimistic-locking 要素コンテンツモデル
- group-name: この要素は、
load-group
のフィールドに基づく楽観ロッキングであることを指定します。この要素のこの値は、エンティティのload-group-name
のいずれかと一致していなければなりません。このグループ内のフィールドが楽観ロッキングに使用されます。 - modified-strategy: この要素は、変更フィールドをベースにした楽観ロッキングであることを指定します。このストラテジーは、トランザクション中に修正されたフィールドが楽観ロッキングに使用されることを意味します。
- read-strategy:この要素は、読み込まれたフィールドに基づく楽観ロッキングであることを指定します。このストラテジーは、トランザクション内の読み込み/変更されたフィールドが楽観ロッキングに使用されることを意味します。
- version-column: この要素は、バージョンカラムストラテジーに基づく楽観ロッキングであることを指定します。この要素を指定すると、楽観ロッキング用にエンティティ bean に
java.lang.Long
タイプの追加のバージョンフィールドが追加されます。エンティティの更新ごとに、このフィールドの値が増えます。field-name
要素は、CMP フィールドの名前の指定を可能にするものであるのに対し、column-name
要素は、対応するテーブルのカラム指定ができるようになります。 - timestamp-column: この要素は、タイムスタンプのカラムストラテジーに基づく楽観ロッキングであることを指定します。この要素を指定すると、楽観ロッキング用にエンティティ bean に
java.util.Date
タイプのバージョンフィールドが別途追加されます。エンティティの更新ごとに、このフィールドの値を現在時刻に設定します。field-name
要素は、CMP フィールドの名前の指定を可能にするものであるのに対し、column-name
要素は、対応するテーブルのカラム指定ができるようになります。 - key-generator-factory:この要素は、キー生成に基づく楽観ロッキングであることを指定します。この要素の値は、
org.jboss.ejb.plugins.keygenerator.KeyGeneratorFactory
実装の JNDI 名です。この要素を指定すると、楽観ロッキング用にエンティティ bean にバージョンフィールドが別途追加されます。フィールドのタイプはfield-type
要素で指定しなければなりません。エンティティの更新ごとに、キージェネレーターから新しい値を取得することでキーフィールドを更新します。field-name
要素は、CMP フィールドの名前の指定を可能にするものであるのに対し、column-name
要素は、対応するテーブルのカラム指定を可能にします。
すべての楽観ロッキングストラテジーを記した
jbosscmp-jdbc.xml
記述子のサンプルを次に示します。
<!DOCTYPE jbosscmp-jdbc PUBLIC "-//JBoss//DTD JBOSSCMP-JDBC 3.2//EN" "http://www.jboss.org/j2ee/dtd/jbosscmp-jdbc_3_2.dtd"> <jbosscmp-jdbc> <defaults> <datasource>java:/DefaultDS</datasource> <datasource-mapping>Hypersonic SQL</datasource-mapping> </defaults> <enterprise-beans> <entity> <ejb-name>EntityGroupLocking</ejb-name> <create-table>true</create-table> <remove-table>true</remove-table> <table-name>entitygrouplocking</table-name> <cmp-field> <field-name>dateField</field-name> </cmp-field> <cmp-field> <field-name>integerField</field-name> </cmp-field> <cmp-field> <field-name>stringField</field-name> </cmp-field> <load-groups> <load-group> <load-group-name>string</load-group-name> <field-name>stringField</field-name> </load-group> <load-group> <load-group-name>all</load-group-name> <field-name>stringField</field-name> <field-name>dateField</field-name> </load-group> </load-groups> <optimistic-locking> <group-name>string</group-name> </optimistic-locking> </entity> <entity> <ejb-name>EntityModifiedLocking</ejb-name> <create-table>true</create-table> <remove-table>true</remove-table> <table-name>entitymodifiedlocking</table-name> <cmp-field> <field-name>dateField</field-name> </cmp-field> <cmp-field> <field-name>integerField</field-name> </cmp-field> <cmp-field> <field-name>stringField</field-name> </cmp-field> <optimistic-locking> <modified-strategy/> </optimistic-locking> </entity> <entity> <ejb-name>EntityReadLocking</ejb-name> <create-table>true</create-table> <remove-table>true</remove-table> <table-name>entityreadlocking</table-name> <cmp-field> <field-name>dateField</field-name> </cmp-field> <cmp-field> <field-name>integerField</field-name> </cmp-field> <cmp-field> <field-name>stringField</field-name> </cmp-field> <optimistic-locking> <read-strategy/> </optimistic-locking> </entity> <entity> <ejb-name>EntityVersionLocking</ejb-name> <create-table>true</create-table> <remove-table>true</remove-table> <table-name>entityversionlocking</table-name> <cmp-field> <field-name>dateField</field-name> </cmp-field> <cmp-field> <field-name>integerField</field-name> </cmp-field> <cmp-field> <field-name>stringField</field-name> </cmp-field> <optimistic-locking> <version-column/> <field-name>versionField</field-name> <column-name>ol_version</column-name> <jdbc-type>INTEGER</jdbc-type> <sql-type>INTEGER(5)</sql-type> </optimistic-locking> </entity> <entity> <ejb-name>EntityTimestampLocking</ejb-name> <create-table>true</create-table> <remove-table>true</remove-table> <table-name>entitytimestamplocking</table-name> <cmp-field> <field-name>dateField</field-name> </cmp-field> <cmp-field> <field-name>integerField</field-name> </cmp-field> <cmp-field> <field-name>stringField</field-name> </cmp-field> <optimistic-locking> <timestamp-column/> <field-name>versionField</field-name> <column-name>ol_timestamp</column-name> <jdbc-type>TIMESTAMP</jdbc-type> <sql-type>DATETIME</sql-type> </optimistic-locking> </entity> <entity> <ejb-name>EntityKeyGeneratorLocking</ejb-name> <create-table>true</create-table> <remove-table>true</remove-table> <table-name>entitykeygenlocking</table-name> <cmp-field> <field-name>dateField</field-name> </cmp-field> <cmp-field> <field-name>integerField</field-name> </cmp-field> <cmp-field> <field-name>stringField</field-name> </cmp-field> <optimistic-locking> <key-generator-factory>UUIDKeyGeneratorFactory</key-generator-factory> <field-type>java.lang.String</field-type> <field-name>uuidField</field-name> <column-name>ol_uuid</column-name> <jdbc-type>VARCHAR</jdbc-type> <sql-type>VARCHAR(32)</sql-type> </optimistic-locking> </entity> </enterprise-beans> </jbosscmp-jdbc>