| Oracle® Fusion Middleware Oracle TopLink Java Persistence API (JPA)拡張機能リファレンス 12c (12.1.2) E48005-01 |
|
![]() 前 |
![]() 次 |
@Partitionedを使用して、エンティティまたはリレーションシップに使用するパーティション・ポリシーを指定します。
注釈要素
表2-47は、この注釈の要素を示しています。
使用方法
パーティション化を使用して、複数のデータベースまたはデータベース・クラスタ(Oracle RACなど)間にあるクラスのデータをパーティション化します。パーティション化することで、複数のデータベース・マシンが要求に応えることができるようになり、スケーラビリティを向上できます。
エンティティ、リレーションシップ、問合せ、またはセッション/永続性ユニットで@Partitionedを指定できます。
パーティション・ポリシー
データのパーティション化を構成するには、@Partitioned注釈および1つ以上のパーティション・ポリシーの注釈を使用します。様々な種類のポリシーを定義する注釈は、次のとおりです。
@HashPartitioning: オブジェクト(オブジェクトのID、場所、テナントなど)からのフィールド値のハッシュによって、データベース・クラスタへのアクセスをパーティション化します。ハッシュによって、接続プール/ノードのリストに索引が付けられます。ハッシュ値を持つオブジェクトに対するすべての書込みまたは読取り要求は、同じサーバーに送信されます。問合せにハッシュがパラメータとして含まれていない場合は、問合せをすべてのサーバーに送信して統合するか、セッションのデフォルトの動作のままにすることができます。
@PinnedPartitioning: 単一の接続プール/ノードへの要求を固定します。これにより、垂直パーティションが可能になります。
@RangePartitioning: オブジェクト(オブジェクトのID、場所、テナントなど)からのフィールド値によって、データベース・クラスタへのアクセスをパーティション化します。各サーバーは、値の範囲に割り当てられます。その値を持つオブジェクトに対するすべての書込みまたは読取り要求は、同じサーバーに送信されます。問合せにフィールドがパラメータとして含まれていない場合は、問合せをすべてのサーバーに送信して統合するか、セッションのデフォルトの動作のままにすることができます。
@ReplicationPartitioning: 要求を一連の接続プール/ノードに送信します。このポリシーは、データベース・マシンのクラスタ間でデータをレプリケートするためのものです。変更問合せのみがレプリケートされます。
@RoundRobinPartitioning: 要求をラウンドロビン方式で一連の接続プール/ノードに送信します。これは、データベース・マシンのクラスタ間で読取り問合せをロード・バランシングするためのものです。パーティション化をサポートしていないため、すべてのデータベースを各マシンでレプリケートする必要があります。データを読取り専用にするか、書込みをレプリケートする必要があります。
@UnionPartitioning: 問合せをすべての接続プールに送信し、結果を統合します。これは、パーティション・リレーションシップ間のManyToManyなど、パーティション化を使用する際にパーティションに及ぶ問合せまたはリレーションシップのためのものです。
@ValuePartitioning: オブジェクト(オブジェクトの場所またはテナントなど)からのフィールド値によって、データベース・クラスタへのアクセスをパーティション化します。各値は、特定のサーバーに割り当てられます。その値を持つオブジェクトに対するすべての書込みまたは読取り要求は、同じサーバーに送信されます。問合せにフィールドがパラメータとして含まれていない場合は、問合せをすべてのサーバーに送信して統合するか、セッションのデフォルトの動作のままにすることができます。
@Partitioning: カスタム・パーティション・ポリシーによって、データベース・クラスタへのアクセスをパーティション化します。PartitioningPolicyクラスを指定および実装する必要があります。
パーティション・ポリシーは、永続性ユニットでグローバルに名付けられたオブジェクトで、複数のディスクリプタまたは問合せ間で再利用できます。特にJPA注釈とXMLを使用することによって、構成のユーザビリティが向上します。
永続性ユニット・プロパティは、読取り/書込み/シーケンスの既存の構成に加えて、名前付き接続プールの追加をサポートします。名前付き接続プールは、データベース・クラスタの各ノードに対して定義される必要があります。
トランザクションによって複数のパーティションからのデータが変更される場合、JTAを使用してデータの2フェーズ・コミットを確認する必要があります。1つのトランザクションに1つのノードのみが使用されるように、EntityManagerで排他接続を構成することもできます。
クラスタ化されたデータベースとOracle RAC
一部のデータベースは、複数のマシン間でのデータベースのクラスタ化をサポートしています。Oracle RACによって、単一のデータベースを複数の異なるサーバー・ノードで使用できます。Oracle RACは、表およびノードのデータのパーティション化もサポートしています。データベース・クラスタにより、クラスタ内のノードからすべてのデータにアクセスできます。ただし、一般的に、特定ノードへのデータ・アクセスをパーティション化し、ノード間の通信を削減することがより効率的です。
TopLinkのパーティション化をクラスタ化されたデータベースとともに使用して、ノード間の通信を削減し、スケーラビリティを向上できます。
データベース・クラスタとともにパーティション化を使用する場合に必要なことは、次のとおりです。
データベース・クラスタによってすべてのノードにデータを使用できるようになるため、パーティション・ポリシーでレプリケーションを有効にしないでください。
データベース・クラスタはすべてのノードから完全な問合せ結果を戻すため、パーティション・ポリシーで統合を使用しないでください。
クラスタの各ノードに対して、データソースおよびTopLink接続プールを定義する必要があります。
各トランザクションが単一ノードへのアクセスのみを必要とするように、アプリケーションのデータ・アクセスおよびデータのパーティション化を設計する必要があります。
1つのトランザクションに複数のノードが含まれないようにするために、また2フェーズ・コミットを回避するために、EntityManagerの排他接続の使用をお薦めします。
例
例2-87に、従業員データを場所別にパーティション化する方法を示します。2つのプライマリ・サイト(オタワおよびトロント)は、異なるデータベースにそれぞれ格納されます。他のすべての場所は、デフォルトのデータベースに格納されます。プロジェクトは、例2-88に示すとおり、IDでレンジ・パーティション化されます。ID値の各範囲は、異なるデータベースに格納されます。従業員/プロジェクト・リレーションシップは、パーティション間リレーションシップの例です。従業員とプロジェクトを異なるデータベースに格納できるようにするには、統合ポリシーを使用して、統合表を各データベースにレプリケートします。
例2-87 パーティション化の使用
@Entity
@IdClass(EmployeePK.class)
@UnionPartitioning(
name="UnionPartitioningAllNodes",
replicateWrites=true)
@ValuePartitioning(
name="ValuePartitioningByLOCATION",
partitionColumn=@Column(name="LOCATION"),
unionUnpartitionableQueries=true,
defaultConnectionPool="default",
partitions={
@ValuePartition(connectionPool="node2", value="Ottawa"),
@ValuePartition(connectionPool="node3", value="Toronto")
})
@Partitioned("ValuePartitioningByLOCATION")
public class Employee {
@Id
@Column(name = "EMP_ID")
private Integer id;
@Id
private String location;
...
@ManyToMany(cascade = { PERSIST, MERGE })
@Partitioned("UnionPartitioningAllNodes")
private Collection<Project> projects;
...
}
例2-88 @RangePartitioningの使用
@Entity
@RangePartitioning(
name="RangePartitioningByPROJ_ID",
partitionColumn=@Column(name="PROJ_ID"),
partitionValueType=Integer.class,
unionUnpartitionableQueries=true,
partitions={
@RangePartition(connectionPool="default", startValue="0", endValue="1000"),
@RangePartition(connectionPool="node2", startValue="1000", endValue="2000"),
@RangePartition(connectionPool="node3", startValue="2000")
})
@Partitioned("RangePartitioningByPROJ_ID")
public class Project {
@Id
@Column(name="PROJ_ID")
private Integer id;
...
}
関連項目
詳細は、次を参照してください。