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の使用