7 TransactionProviderの使用方法
この章では、Oracle OLAP Java APIのTransactionおよびTransactionProviderインタフェースについて説明し、アプリケーションでのこれらのインタフェースの実装の使用方法について説明します。 DataProviderからTransactionProviderを取得します。 TransactionProviderのcommitCurrentTransactionメソッドを使用して、メタデータ・オブジェクトをデータベースの永続記憶域に保存します。 また、導出されたSourceを作成した後、SourceのCursorを作成する前に、このメソッドを使用します。 メタデータ・オブジェクトの作成後にTransactionをコミットする例は、「メタデータおよびアナリティク・ワークスペースの作成」を参照してください。
この章では、次の項目について説明します。
7.1 トランザクションでのメタデータ・オブジェクトまたは問合せの作成について
Oracle OLAP Java APIは、トランザクション処理を行います。 問合せのメタデータ・オブジェクトまたはSourceオブジェクトの作成は、Transactionのコンテキストで行われます。 TransactionProviderは、アプリケーションにTransactionオブジェクトを提供し、それらのTransactionオブジェクトをコミットまたは破棄します。
TransactionProviderでは、次のことが保証されます:
-
Transactionは、他のTransactionオブジェクトから分離されています。Transactionで実行された操作は、他のTransactionオブジェクトには表示されず、影響もありません。 -
Transaction内の操作が失敗した場合、操作の効果は元に戻されます(Transactionはロールバックされます)。 -
完了した
Transactionの影響は維持されます。
DataProviderおよびUserSessionを作成する場合、セッションには最初はTransactionがありません。 セッションの最初のTransactionは、ルートTransactionです。 TransactionProviderのcreateRootTransactionメソッドをコールして、ルートTransactionを明示的に作成できます。 明示的に作成しない場合、Oracle OLAPは、MdmObjectまたは導出されたSourceを初めて作成または変更するときに、ルートTransactionを自動的に作成します。 MdmObjectに変更を永続化するには、変更を加えたルートTransactionをコミットする必要があります。
単一ユーザー・アプリケーションは、ルートTransactionを明示的に作成する必要はありません。 複数のルートTransactionオブジェクトを作成する機能は、マルチスレッドの中間層アプリケーションで使用するために提供されます。 アプリケーションで複数のルートTransactionオブジェクトを使用する場合、あるルートTransactionでアプリケーションが実行する変更は、別のルートTransactionでアプリケーションが実行する変更によって上書きできます。 アプリケーションがコミットする最後のルートTransactionで発生する変更は、永続的に変更されます。
ユーザーまたはOracle OLAPが初期ルートTransactionを作成すると、current Transactionになります。 別のルートTransactionを作成すると、現在のTransactionになります。
Oracle OLAPは、ルートTransactionの下にSourceオブジェクトまたは子Transactionオブジェクトを作成するときに、他のTransactionオブジェクトを作成します。 Oracle DatabaseのルートTransactionをコミットして、セッション内の任意のTransactionで作成したメタデータ・オブジェクトを永続ストレージに追加する必要があります。
別のSourceのメソッドをコールして導出されたSourceを作成すると、現在のTransactionのコンテキストで導出されたSourceが作成されます。 Sourceは、作成するTransactionの「アクティブ」、またはそのTransactionの子Transactionの「アクティブ」です。
TransactionProviderのメソッドをコールして、現在のTransactionを取得または設定するか、子Transactionを開始します。 子のTransactionでは、問合せを変更できます。たとえば、ディメンション要素の選択を変更したり、データに対して別の数学的操作またはアナリティク操作を実行することで、親のTransactionで作成したTemplateの状態を変更できます。 親TransactionのTemplateによって生成されたSourceによって指定されたデータを表示し、子TransactionのTemplateによって生成されたSourceによって指定されたデータも表示することで、次のことができます。アプリケーションのエンド・ユーザーに、問合せを簡単に変更し、同じデータ・セットに対して異なる操作の結果を表示したり、異なるデータ・セットに対して同じ操作を実行したりする手段を提供します。
- Transactionオブジェクトのタイプ
- Transactionのコミット
- TransactionおよびTemplateオブジェクト
- 子Transactionの開始
- Transactionのロールバック
- 現行のTransactionの取得および設定
親トピック: TransactionProviderの使用
7.1.1 Transactionオブジェクトのタイプ
OLAP Java APIには、次の2タイプのTransactionオブジェクトがあります:
-
「読む」
Transaction。 最初は、現在のTransactionは読取りTransactionです。 Oracle OLAPからデータをフェッチするCursorを作成するには、読取りTransactionが必要です。Cursorオブジェクトの詳細は、「問合せ結果の取得中」を参照してください。 -
「書く」
Transaction。 導出されたSourceの作成またはTemplateの状態の変更には、書込みTransactionが必要です。 導出されたSourceの作成の詳細は、「Sourceオブジェクトの理解」を参照してください。Templateオブジェクトの詳細は、「動的問合せの作成」を参照してください。
初期読取りTransactionで、導出されたSourceを作成した場合、またはTemplateオブジェクトの状態を変更した場合は、子書込みTransactionが自動的に生成されます。 その子Transactionが現在のTransactionになります。
次に、別の導出Sourceを作成するか、Template状態を再び変更すると、その操作は同じ書込みTransactionで行われます。 同じ書込みTransactionで、任意の数の導出Sourceオブジェクトを作成することも、任意の数のTemplate状態変更を行うこともできます。 これらのSourceオブジェクト、またはTemplateによって生成されたSourceを使用して、複雑な問合せを定義できます。
Cursorを作成して、導出されたSourceで指定された結果セットをフェッチする前に、Sourceを子書込みTransactionから親読取りTransactionに移動する必要があります。 これを行うには、Transactionをコミットします。
7.1.2 Transactionのコミット
子Transactionで作成したSourceを親の読取りTransactionに移動するには、TransactionProviderのcommitCurrentTransactionメソッドをコールします。 子書込みTransactionをコミットすると、子Transactionで作成したSourceが親読取りTransactionに移動します。 子Transactionは表示されなくなり、親Transactionが現在のTransactionになります。 Sourceは、現在の読取りTransactionでアクティブであるため、そのCursorを作成できます。
例7-1 現行のTransactionのコミット
この例では、commit()は現在のTransactionをコミットするメソッドです。 この例では、dpはDataProviderです。
private void commit()
{
try
{
(dp.getTransactionProvider()).commitCurrentTransaction();
}
catch (Exception ex)
{
System.out.println("Could not commit the Transaction. " + ex);
}
}7.1.3 TransactionおよびTemplateオブジェクト
現在のTransactionを取得および設定し、子Transactionを開始し、Transactionをロールバックすることは、エンド・ユーザーが動的問合せの特定の状態から異なる選択を行えるようにするために使用する操作です。
エンド・ユーザーに同じ最初の問合せに基づいた代替を提供するには、次の手順を実行します。
-
親
TransactionにTemplateを作成し、Templateの初期状態を設定します。 -
Templateによって生成されたSourceを取得し、Cursorを作成して結果セットを取得し、Cursorから値を取得してから、結果をエンド・ユーザーに表示します。 -
子
Transactionを起動し、Templateの状態を変更します。 -
子
TransactionでTemplateによって生成されたSourceを取得し、Cursorを作成し、値を取得して表示します。
その後、最初のTemplate状態を2番目の状態に置き換えるか、2番目の状態を破棄して最初の状態を保持できます。
7.1.4 子Transactionの開始
子読取りTransactionを開始するには、使用しているTransactionProviderのbeginSubtransactionメソッドをコールします。 子読取りTransactionで、Templateの状態を変更すると、子書込みTransactionが自動的に開始されます。 書込みTransactionは、子読取りTransactionの子です。
Templateによって生成されたSourceで指定されたデータを取得するには、書込みTransactionを親読取りTransactionにコミットします。 その後、Cursorを作成してデータをフェッチできます。 Templateの変更された状態は、元の親には表示されません。 変更された状態は、子読取りTransactionを親読取りTransactionにコミットするまで、親には表示されません。
子読取りTransactionを開始した後、その子読取りTransaction、または最初の親Transactionの孫を開始できます。 子および孫のTransactionオブジェクトの作成例は、「例7-3」を参照してください。
7.1.5 Transactionのロールバック
使用しているTransactionProviderのrollbackCurrentTransactionメソッドをコールして、Transactionをロールバックまたは元に戻します。 Transactionをロールバックすると、そのTransaction中に行ったすべての変更が破棄され、Transactionが消えます。
Transactionをロールバックする前に、そのTransactionで作成したCursorManagerオブジェクトをクローズする必要があります。 Transactionをロールバックした後、Transactionで作成したSourceオブジェクトまたはTemplate状態の変更は無効になります。 それらのSourceオブジェクトに対して作成したCursorオブジェクトもすべて無効です。
Transactionをロールバックすると、そのTransactionをコミットできません。 同様に、Transactionをコミットすると、ロールバックできません。
例7-2 Transactionのロールバック
この例では、「動的問合せの作成」で説明されているTopBottomTemplateおよびSingleSelectionTemplateクラスを使用します。 この例では、TopBottomTemplateおよびSingleSelectionTemplateオブジェクトの作成で、「例10-4」に表示されるものと同じコードを使用します。 この例には、そのコードは表示されていません。 TopBottomTemplateの状態を設定します。 TopBottomTemplateに別の状態を設定する子Transactionを開始し、子Transactionをロールバックします。 printlnメソッドは、CursorPrintWriterオブジェクトを介してテキストを表示し、getContextメソッドは、Cursorオブジェクトを作成し、CursorPrintWriterを介してその値を表示するメソッドを持つContext11gオブジェクトを取得します。 CursorPrintWriterおよびContext11gクラスは、このドキュメントのサンプル・プログラムで使用されます。
// The current Transaction is a read Transaction, t1.
// Create a TopBottomTemplate using a hierarchy of the PRODUCT_AWJ dimension
// as the base and dp as the DataProvider.
TopBottomTemplate topNBottom = new TopBottomTemplate(prodHier, dp);
// Changing the state of a Template requires a write Transaction, so a
// write child Transaction, t2, is automatically started.
topNBottom.setTopBottomType(TopBottomTemplate.TOP_BOTTOM_TYPE_TOP);
topNBottom.setN(10);
topNBottom.setCriterion(singleSelections.getSource());
// Get the TransactionProvider and commit the Transaction t2.
TransactionProvider tp = dp.getTransactionProvider();
try
{
tp.commitCurrentTransaction(); // t2 disappears
}
catch(Exception e)
{
println("Cannot commit the Transaction. " + e);
}
// The current Transaction is now t1.
// Get the dynamic Source produced by the TopBottomTemplate.
Source result = topNBottom.getSource();
// Create a Cursor and display the results
println("\nThe current state of the TopBottomTemplate" +
"\nproduces the following values:\n");
getContext().displayTopBottomResult(result);
// Start a child Transaction, t3. It is a read Transaction.
tp.beginSubtransaction(); // t3 is the current Transaction
// Change the state of topNBottom. Changing the state requires a
// write Transaction so Transaction t4 starts automatically.
topNBottom.setTopBottomType(TopBottomTemplate.TOP_BOTTOM_TYPE_BOTTOM);
topNBottom.setN(15);
// Commit the Transaction.
try
{
tp.commitCurrentTransaction(); // t4 disappears
}
catch(Exception e)
{
println("Cannot commit the Transaction. " + e);
}
// Create a Cursor and display the results. // t3 is the current Transaction
println("\nIn the child Transaction, the state of the" +
"\nTopBottomTemplate produces the following values:\n");
getContext().displayTopBottomResult(result);
// The displayTopBottomResult method closes the CursorManager for the
// Cursor created in t3.
// Undo t3, which discards the state of topNBottom that was set in t4.
tp.rollbackCurrentTransaction(); // t3 disappears
// Transaction t1 is now the current Transaction and the state of
// topNBottom is the one defined in t2.
// To show the current state of the TopNBottom template Source, commit
// the Transaction, create a Cursor, and display the Cursor values.
try
{
tp.commitCurrentTransaction();
}
catch(Exception e)
{
println("Cannot commit the Transaction. " + e);
}
println("\nAfter rolling back the child Transaction, the state of"
+ "\nthe TopBottomTemplate produces the following values:\n");
getContext().displayTopBottomResult(result);
この例では、次の出力が生成されます。
The current state of the TopBottomTemplate produces the following values: 1. PRODUCT_PRIMARY::TOTAL_PRODUCT::TOTAL 2. PRODUCT_PRIMARY::CLASS::SFT 3. PRODUCT_PRIMARY::FAMILY::ACC 4. PRODUCT_PRIMARY::CLASS::HRD 5. PRODUCT_PRIMARY::FAMILY::MOD 6. PRODUCT_PRIMARY::FAMILY::OS 7. PRODUCT_PRIMARY::FAMILY::DISK 8. PRODUCT_PRIMARY::ITEM::MOUSE PAD 9. PRODUCT_PRIMARY::ITEM::OS 1 USER 10. PRODUCT_PRIMARY::ITEM::DLX MOUSE In the child Transaction, the state of the TopBottomTemplate produces the following values: 1. PRODUCT_PRIMARY::ITEM::EXT CD ROM 2. PRODUCT_PRIMARY::ITEM::OS DOC ITA 3. PRODUCT_PRIMARY::ITEM::OS DOC SPA 4. PRODUCT_PRIMARY::ITEM::INT CD USB 5. PRODUCT_PRIMARY::ITEM::ENVY EXT KBD 6. PRODUCT_PRIMARY::ITEM::19 SVGA 7. PRODUCT_PRIMARY::ITEM::OS DOC FRE 8. PRODUCT_PRIMARY::ITEM::OS DOC GER 9. PRODUCT_PRIMARY::ITEM::ENVY ABM 10. PRODUCT_PRIMARY::ITEM::INT CD ROM 11. PRODUCT_PRIMARY::ITEM::ENVY EXE 12. PRODUCT_PRIMARY::ITEM::OS DOC KAN 13. PRODUCT_PRIMARY::ITEM::ENVY STD 14. PRODUCT_PRIMARY::ITEM::1GB USB DRV 15. PRODUCT_PRIMARY::ITEM::SENT MM After rolling back the child Transaction, the state of the TopBottomTemplate produces the following values: 1. PRODUCT_PRIMARY::TOTAL_PRODUCT::TOTAL 2. PRODUCT_PRIMARY::CLASS::SFT 3. PRODUCT_PRIMARY::FAMILY::ACC 4. PRODUCT_PRIMARY::CLASS::HRD 5. PRODUCT_PRIMARY::FAMILY::MOD 6. PRODUCT_PRIMARY::FAMILY::OS 7. PRODUCT_PRIMARY::FAMILY::DISK 8. PRODUCT_PRIMARY::ITEM::MOUSE PAD 9. PRODUCT_PRIMARY::ITEM::OS 1 USER 10. PRODUCT_PRIMARY::ITEM::DLX MOUSE
7.2 TransactionProviderオブジェクトの使用方法
Oracle OLAP Java APIでは、DataProviderはTransactionProviderインタフェースの実装を提供します。 TransactionProviderは、アプリケーションにTransactionオブジェクトを提供します。
「トランザクションのコミット」で説明されているように、commitCurrentTransactionメソッドを使用して、子書込みTransactionで作成した導出Sourceを親読取りTransactionで表示できるようにします。 その後、そのSourceのCursorを作成できます。
アプリケーションでTemplateオブジェクトを使用している場合は、TransactionProviderの他のメソッドを使用して次の操作を行うこともできます:
-
子
Transactionを開始します。 -
現在の
Transactionを取得して保存します。 -
現在の
Transactionを以前に保存したものに設定します。 -
Transactionで行われた変更を破棄する現在のTransactionをロールバックまたは元に戻します。Transactionは、一度ロールバックされると無効になり、コミットできません。Transactionは、コミット後はロールバックできません。TransactionでSourceのCursorを作成した場合は、Transactionをロールバックする前にCursorManagerを閉じる必要があります。
「例7-3」は、Transactionオブジェクトを使用した動的問合せの変更を示しています。 「例7-2」と同様、この例では、「例10-4」と同じコードを使用してTopBottomTemplateおよびSingleSelectionTemplateオブジェクトを作成します。 この例には、そのコードは表示されていません。
Transactionオブジェクトの追跡に役立つように、この例では、getCurrentTransactionメソッドへのコールを使用して様々なTransactionオブジェクトを保存します。 この例では、tpオブジェクトはTransactionProviderです。 printlnメソッドは、CursorPrintWriterを介してテキストを表示し、getContextメソッドは、Cursorオブジェクトを作成し、CursorPrintWriterを介してその値を表示するメソッドを持つContext11gオブジェクトを取得します。 commitメソッドは、「例7-1」のメソッドです。
例7-3 子Transactionオブジェクトの使用方法
// The parent Transaction is the current Transaction at this point.
// Save the parent read Transaction as parentT1.
Transaction parentT1 = tp.getCurrentTransaction();
// Get the dynamic Source produced by the TopBottomTemplate.
Source result = topNBottom.getSource();
// Create a Cursor and display the results.
println("\nThe current state of the TopBottomTemplate" +
"\nproduces the following values:\n");
getContext().displayTopBottomResult(result);
// Begin a child Transaction of parentT1.
tp.beginSubtransaction(); // This is a read Transaction.
// Save the child read Transaction as childT2.
Transaction childT2 = tp.getCurrentTransaction();
// Change the state of the TopBottomTemplate. This starts a
// write Transaction, a child of the read Transaction childT2.
topNBottom.setN(12);
topNBottom.setTopBottomType(TopBottomTemplate.TOP_BOTTOM_TYPE_BOTTOM);
// Save the child write Transaction as writeT3.
Transaction writeT3 = tp.getCurrentTransaction();
// Commit the write Transaction writeT3.
commit();
// The commit moves the changes made in writeT3 into its parent,
// the read Transaction childT2. The writeT3 Transaction
// disappears. The current Transaction is now childT2
// again but the state of the TopBottomTemplate has changed.
// Create a Cursor and display the results of the changes to the
// TopBottomTemplate that are visible in childT2.
try
{
println("\nIn the child Transaction, the state of the" +
"\nTopBottomTemplate produces the following values:\n");
getContext().displayTopBottomResult(result);
}
catch(Exception e)
{
println("Cannot display the results of the query. " + e);
}
// Begin a grandchild Transaction of the initial parent.
tp.beginSubtransaction(); // This is a read Transaction.
// Save the grandchild read Transaction as grandchildT4.
Transaction grandchildT4 = tp.getCurrentTransaction();
// Change the state of the TopBottomTemplate. This starts another
// write Transaction, a child of grandchildT4.
topNBottom.setTopBottomType(TopBottomTemplate.TOP_BOTTOM_TYPE_TOP);
// Save the write Transaction as writeT5.
Transaction writeT5 = tp.getCurrentTransaction();
// Commit writeT5.
commit();
// Transaction grandchildT4 is now the current Transaction and the
// changes made to the TopBottomTemplate state are visible.
// Create a Cursor and display the results visible in grandchildT4.
try
{
println("\nIn the grandchild Transaction, the state of the" +
"\nTopBottomTemplate produces the following values:\n");
getContext().displayTopBottomResult(result);
}
catch(Exception e)
{
println(""Cannot display the results of the query. " + e);
}
// Commit the grandchild into the child.
commit();
// Transaction childT2 is now the current Transaction.
// Instead of preparing and committing the grandchild Transaction,
// you could rollback the Transaction, as in the following
// method call:
// rollbackCurrentTransaction();
// If you roll back the grandchild Transaction, then the changes
// you made to the TopBottomTemplate state in the grandchild
// are discarded and childT2 is the current Transaction.
// Commit the child into the parent.
commit();
// Transaction parentT1 is now the current Transaction. Again,
// you can roll back the childT2 Transaction instead of committing it.
// If you do so, then the changes that you made in childT2 are discarded.
// The current Transaction is be parentT1, which has the original state
// of the TopBottomTemplate, without any of the changes made in the
// grandchild or the child transactions.
例7-3の出力は、次のようになります。
The current state of the TopBottomTemplate produces the following values: 1. PRODUCT_PRIMARY::TOTAL_PRODUCT::TOTAL 2. PRODUCT_PRIMARY::CLASS::SFT 3. PRODUCT_PRIMARY::FAMILY::ACC 4. PRODUCT_PRIMARY::CLASS::HRD 5. PRODUCT_PRIMARY::FAMILY::MOD 6. PRODUCT_PRIMARY::FAMILY::OS 7. PRODUCT_PRIMARY::FAMILY::DISK 8. PRODUCT_PRIMARY::ITEM::MOUSE PAD 9. PRODUCT_PRIMARY::ITEM::OS 1 USER 10. PRODUCT_PRIMARY::ITEM::DLX MOUSE In the child Transaction, the state of the TopBottomTemplate produces the following values: 1. PRODUCT_PRIMARY::ITEM::EXT CD ROM 2. PRODUCT_PRIMARY::ITEM::OS DOC ITA 3. PRODUCT_PRIMARY::ITEM::OS DOC SPA 4. PRODUCT_PRIMARY::ITEM::INT CD USB 5. PRODUCT_PRIMARY::ITEM::ENVY EXT KBD 6. PRODUCT_PRIMARY::ITEM::19 SVGA 7. PRODUCT_PRIMARY::ITEM::OS DOC FRE 8. PRODUCT_PRIMARY::ITEM::OS DOC GER 9. PRODUCT_PRIMARY::ITEM::ENVY ABM 10. PRODUCT_PRIMARY::ITEM::INT CD ROM 11. PRODUCT_PRIMARY::ITEM::ENVY EXE 12. PRODUCT_PRIMARY::ITEM::OS DOC KAN In the grandchild Transaction, the state of the TopBottomTemplate produces the following values: 1. PRODUCT_PRIMARY::TOTAL_PRODUCT::TOTAL 2. PRODUCT_PRIMARY::CLASS::SFT 3. PRODUCT_PRIMARY::FAMILY::ACC 4. PRODUCT_PRIMARY::CLASS::HRD 5. PRODUCT_PRIMARY::FAMILY::MOD 6. PRODUCT_PRIMARY::FAMILY::OS 7. PRODUCT_PRIMARY::FAMILY::DISK 8. PRODUCT_PRIMARY::ITEM::MOUSE PAD 9. PRODUCT_PRIMARY::ITEM::OS 1 USER 10. PRODUCT_PRIMARY::ITEM::DLX MOUSE 11. PRODUCT_PRIMARY::ITEM::LT CASE 12. PRODUCT_PRIMARY::ITEM::56KPS MODEM
親トピック: TransactionProviderの使用