クライアント・アプリケーションは、oracle.jbo.Transaction
インタフェースを使用し、データベースへの接続およびトランザクションの管理を行います。アプリケーション・モジュールで有効なTransaction
インタフェースのメソッドは、次のとおりです。
commit
: トランザクションをコミットし、データベースへのすべての変更を保存します。データベース接続が確立されていれば、トランザクションは暗黙的に開始されます。
connect
: 特定のデータベースURLへの接続を試行します。
disconnect
: データベース接続を切断します。
getLockingMode
: このトランザクションの優先ロック・モードを取得します。現在、デフォルトのロック・モードはLOCK_PESSIMISTIC
です。
rollback
: トランザクションをロールバックし、すべての変更を破棄します。
setLockingMode
: このトランザクションの優先ロック・モードを設定します。ロック・モードの変更は、その後のロックにのみ影響します。
クライアントは、ビジネス・ロジック層のコンポーネントにより提供されるアプリケーション・モジュールを使用するか、またはBusiness Components for Javaフレームワークにより提供されるデフォルトのアプリケーション・モジュールを使用できます。データベースに接続している場合、アプリケーション・モジュールによりトランザクションの境界が定義されます。アプリケーション・モジュールによりデータベースの変更がコミットされると、更新されたデータは他のアプリケーション・モジュールにも使用可能になります。次の図に、AppMod1
およびAppMod2
の2つのアプリケーション・モジュールを示します。AppMod1
では、DeptEmpView
およびEmpView
は、エンティティ・オブジェクトを使用してDEPT表とEMP表にアクセスします。AppMod2
も、EmpView
を使用します。しかし、あるアプリケーション・モジュールでデータが変更された場合、トランザクションがコミットされるまで、その変更は他のアプリケーション・モジュールでは使用できません。たとえば、AppMod1
内のEmpView
によりEMPが更新されたが、変更がコミットされていない場合、DeptEmpView
は新しいデータにアクセスできますが、AppMod2
内のEmpView
はアクセスできません。
ビジネス・ロジック層のコンポーネントにカスタム・アプリケーション・モジュールがない場合、クライアント・アプリケーションでは、データベースへ接続してトランザクションを開始するために、Business Components for Javaフレームワークにより用意された汎用アプリケーション・モジュールを使用してトランザクションを取得する必要があります。次のコード例は、アプリケーション・モジュールによりどのようにトランザクションのコンテキストが提供されるかを示しています。コードでは、変数appMod
で表されるアプリケーション・モジュールが他の場所で宣言および初期化されていること、およびトランザクションがconnect()
メソッドを使用して開始されていることを前提としています。また、ビュー・オブジェクトvo
の1行をnewAttrVal
という値で更新するためのupdateAttr
というメソッドが実装されていることも前提にしています。updateAttr
が成功した(trueが返された)場合、コードによりトランザクションがコミットされます。そうでない場合、トランザクションはロールバックされます。
// Assume that appMod has been declared and initialized elsewhere.
try {
if (updateAttr(vo, newAttrVal)) {
// Commit changes to the database, making
// updated data available to other application modules.
appMod.getTransaction().commit();
System.out.println("\n Transaction committed. \n");
}
else {
appMod.getTransaction().rollback();
System.out.println("\n Transaction rolled back. \n");
}
} catch (Exception e) {
e.printStackTrace();
}
アプリケーション・モジュールはネストできます。つまり、(論理的には)アプリケーション・モジュールに、ビュー・オブジェクト以外にも1つ以上の他のアプリケーション・モジュールを含めることができます。アプリケーション・モジュールがネストしている場合、最も外側(最上位レベル)のアプリケーション・モジュールが他のモジュールのトランザクション・コンテキストを提供します。次の図に、2つの例を示します。最初の例では、amTwo
がamThree
を含んでいますが、amOne
が一番外側のアプリケーション・モジュールであるためamTwo
はトランザクション・コンテキストを提供しません。2つ目の例では、汎用アプリケーション・モジュールが一番外側であるため、これがamFour
のトランザクション・コンテキストを提供しています。
最上位レベルのアプリケーション・モジュールでは、関連する一連の問合せのトランザクション・コンテキストを定義し、独立したフォームからのデータ変更の同じトランザクションへの結合をサポートします。アプリケーション・モジュールを共有することにより、複数のフォームで同じトランザクションを使用でき、それらのフォームは、共有アプリケーション・モジュールからビュー・オブジェクトを渡すことができます。
挿入や削除などのデータ変更は、同じトランザクション内の他のアプリケーション・モジュールによりただちに検出されます。同様に、属性への変更はビュー・オブジェクトによりただちに検出されます。
エンティティ・オブジェクトは、データベース・オブジェクトを表します。エンティティ・オブジェクトによりデータがキャッシュされ、基礎となるデータベース・オブジェクトへのマッピングが提供されます。トランザクションではキャッシュが管理され、データは1つのデータベースと同期化されます。エンティティ・オブジェクトは、クライアント層には直接公開されません。クライアントは、アプリケーション・モジュール内のビュー・オブジェクトを介してエンティティ・オブジェクトのデータにアクセスします。トランザクション内のビュー・オブジェクトはすべて、同じエンティティ・キャッシュを共有します。ビュー・オブジェクトとエンティティ・オブジェクトは、(リモート・インタフェース・プロキシではなく)イベントまたはJavaのコール(あるいはその両方)を介して通信します。
ビュー・オブジェクトは基礎となるエンティティ・オブジェクトに対する問合せとして表され、プレゼンテーション層のための結果セットが作成されます。データはエンティティ・オブジェクト・レベルでキャッシュされ、同じトランザクション内のすべてのビュー・オブジェクト参照はエンティティ・オブジェクトを共有しているため、あるビュー・オブジェクトを介して行われた変更は、同じトランザクション内の他のビュー・オブジェクトでただちに使用可能になります。
次のコード例は、値が変更、ポストおよびコミットされた際のアプリケーション・モジュール、ビュー・オブジェクトおよびデータベース間の相互作用を示しています。
package amdemo;
import oracle.jbo.*;
import java.util.Hashtable;
import javax.naming.*;
public class TestAm {
public static void main(String[] args) {
final String amName1 = "am1.AppMod1";
final String amName2 = "am2.AppMod2";
final String voName1 = "am1.DeptView1";
final String voName2 = "am1.DeptView2";
final String voName3 = "am2.DeptView3";
final String voName4 = "am2.DeptView4";
final String connStr = "jdbc:oracle:thin:scott/tiger@jtora815:1521:ORCL";
// Set environment for local deployment.
Hashtable env = new Hashtable(2);
env.put(Context.INITIAL_CONTEXT_FACTORY, JboContext.JBO_CONTEXT_FACTORY);
env.put(JboContext.DEPLOY_PLATFORM, JboContext.PLATFORM_LOCAL);
ApplicationModule appMod1 = null;
ApplicationModule appMod2 = null;
try {
javax.naming.Context ic = new InitialContext(env);
ApplicationModuleHome home1 =
(ApplicationModuleHome)ic.lookup(amName1);
appMod1 = home1.create();
appMod1.getTransaction().connect(connStr);
ApplicationModuleHome home2 =
(ApplicationModuleHome)ic.lookup(amName2);
appMod2 = home2.create();
appMod2.getTransaction().connect(connStr);
} catch(Exception e){
e.printStackTrace();
}
ViewObject vo1 = appMod1.createViewObject("vo1", voName1);
ViewObject vo2 = appMod1.createViewObject("vo2", voName2);
ViewObject vo3 = appMod2.createViewObject("vo3", voName3);
//ViewObject vo4 = appMod2.createViewObject("vo4", voName4);
Row r1 = vo1.first();
r1.setAttribute("Loc", "asdf");
System.out.println("vo1 before AppMod1 post " + r1.getAttribute("Loc"));
Row r2 = vo2.first();
System.out.println("vo2 before AppMod1 post " + r2.getAttribute("Loc"));
vo3.executeQuery();
Row r3 = vo3.first();
System.out.println("vo3 before AppMod1 post " + r3.getAttribute("Loc"));
//Row r4 = vo4.first();
//System.out.println("vo4 before AppMod1 post " + r4.getAttribute("Loc"));
appMod1.getTransaction().postChanges();
System.out.println("vo1 after AppMod1 post " + r1.getAttribute("Loc"));
r2 = vo2.first();
System.out.println("vo2 after AppMod1 post " + r2.getAttribute("Loc"));
r3 = vo3.first();
System.out.println("vo3 after AppMod1 post " + r3.getAttribute("Loc"));
//r4 = vo4.first();
//System.out.println("vo4 after AppMod1 post " + r4.getAttribute("Loc"));
try {
appMod1.getTransaction().commit();
System.out.println("Commit succeeded.");
} catch (oracle.jbo.JboException e) {
System.out.println("Commit failed. " + e);
}
System.out.println("vo1 after AppMod1 commit " + r1.getAttribute("Loc"));
r2 = vo2.first();
System.out.println("vo2 after AppMod1 commit " + r2.getAttribute("Loc"));
vo3.executeQuery();
r3 = vo3.first();
System.out.println("vo3 after AppMod1 commit " + r3.getAttribute("Loc"));
//r4 = vo4.first();
//System.out.println("vo4 after AppMod1 commit " + r4.getAttribute("Loc"));
// Keep the console window open so you can see what happened.
System.out.println("\n Press Enter to close this window.");
try { System.in.read(); } catch (Exception e) {}
}
}