Sun Java System Application Server Enterprise Edition 8.2 パフォーマンスチューニングガイド

バージョン整合性

データベース内のデータの完全性を保護しながらパフォーマンスを改善するには、「バージョン整合性」を使用します。アプリケーションサーバーは EJB コンポーネントの複数のコピーを同時に使用できるので、同時アクセスを通じて EJB コンポーネントが破壊された状態になる可能性があります。

破壊を防ぐ標準的な方法は、特定の Bean に関連付けられたデータベース行をロックすることです。これは、2 つの同時トランザクションによって Bean がアクセスされることを防ぎ、結果的にデータを保護します。ただし、この方法は実質的にすべての EJB アクセスを直列化するため、パフォーマンスも低下させます。

バージョン整合性は、EJB データの完全性を保護するためのもう 1 つのアプローチです。バージョン整合性を使用するには、バージョン番号として使用するデータベース内の列を指定します。その場合、EJB ライフサイクルの進行は次のようになります。

2 回目以降の Bean の使用では、ejbLoad() メソッドがその初期データ (バージョン番号を含む) を内部キャッシュからロードすることを除いて、動作は同様です。これにより、データベースへのアクセスが省略されます。ejbStore() メソッドが呼び出されると、トランザクションで正しいデータが使用されたことを保証するためにバージョン番号がチェックされます。

バージョンが一致していると、2 つのトランザクションが同じ EJB コンポーネントを同時に使用できるため、めったに変更されない EJB コンポーネントがある場合には効果的な手法です。どちらのトランザクションもデータを変更しないため、両方のトランザクションの終了時にバージョン番号は不変のままであり、トランザクションは両方とも成功します。ただし、この時点ではトランザクションの並列実行が可能です。2 つのトランザクションが同じ EJB コンポーネントを変更する場合、一方が成功し、もう一方は失敗して、新しい値を使用して再試行することができます。これは、再試行の頻度が一定以下であれば、EJB コンポーネントへのすべてのアクセスを直列化するよりも高速です (ただし、再試行操作を実行するための新しいアプリケーションロジックを準備する必要がある)。

バージョン整合性を使用するには、特定のテーブル用のデータベーススキーマに、バージョンを格納できる列を含める必要があります。その後、特定の Bean に対する配備記述子 sun-cmp-mapping.xml でそのテーブルを指定します。

<entity-mapping>
    <cmp-field-mapping>
        ...
    </cmp-field-mapping>
    <consistency>
        <check-version-of-accessed-instances>
            <column-name>OrderTable.VC_VERSION_NUMBER</column-name>
        </check-version-of-accessed-instances>
    </consistency>
</entity-mapping>

加えて、指定されたテーブル内のデータが変更されたときにバージョン列を自動的に更新するためのトリガーを、データベースに対して確立する必要があります。Application Server では、そのようなトリガーはバージョン整合性を使用する必要があります。そのようなトリガーを定義することにより、EJB データを変更する外部アプリケーションが、進行中の EJB トランザクションと競合しないことも保証されます。

たとえば、次の DDL は、Order テーブルのトリガーを作成する方法を例示します。

CREATE TRIGGER OrderTrigger
  BEFORE UPDATE ON OrderTable
  FOR EACH ROW
  WHEN (new.VC_VERSION_NUMBER = old.VC_VERSION_NUMBER)
  DECLARE
  BEGIN
    :NEW.VC_VERSION_NUMBER := :OLD.VC_VERSION_NUMBER + 1;
  END;