Oracle8i Enterprise JavaBeans and CORBA Developer's Guide
Release 8.1.5

A64683-01

Library

Product

Contents

Index

Prev  Chap Top Next

Transaction Examples

clientside

readme.txt

Overview
========


The clientside example shows how to do transaction management for
CORBA server objects from the client application, using the XA JTS
methods.

This example also shows a server object that uses SQLJ in its methods.



Source files
============

employee.idl
------------

The CORBA IDL for the example.  Defines:

An EmployeeInfo struct
A SQLError exception
An Employee interface, with
    EmployeeInfo getEmployee ()
    void updateEmployee ()

The SQLError exception is used so that SQLException messages can 
be passed back to the client.  


Client.java
-----------

You invoke the client program from a command prompt, and pass it four
arguments, the

   - service URL (service ID, hostname, port, and SID if port is a listener)
   - name of the published server object to lookup and instantiate
   - username
   - password that authenticates the client to the Oracle8i database server

For example:
% java -classpath LIBs Client sess_iiop://localhost:2481:ORCL \
        /test/myEmployee scott tiger


where LIBs is the classpath that must include

$ORACLE_HOME/lib/aurora_client.jar
$ORACLE_HOME/jdbc/lib/classes111.zip
$ORACLE_HOME/lib/vbjorb.jar
$ORACLE_HOME/lib/vbjapp.jar
$JAVA_HOME/lib/classes.zip

(Note: for NT users, the environment variables would be %ORACLE_HOME% and
%JAVA_HOME%.)

The client code performs the following steps:

   - gets the arguments passed on the command line
   - creates a new JNDI Context (InitialContext())
   - initializes the Aurora transaction service
   - looks up the myEmployee CORBA published object on the server
       (this step also authenticates the client using NON_SSL_LOGIN and
        activates the server object)
   - starts a new transaction: TS.getTS().getCurrent().begin();
   - gets and prints information about the employee SCOTT
   - increases SCOTT's salary by 10%
   - updates the EMP table with the new salary by calling the updateEmployee()
        method on the employee object
   - gets and prints the new information
   - commits the update: TS.getTS().getCurrent().commit(false);

The printed output is:

SCOTT 7788 3000.0
SCOTT 7788 3300.0


employeeServer/EmployeeImpl.sqlj
--------------------------------

Implements the Employee interface.  This file implements the two
methods specified in the IDL: getEmployee() and updateEmployee(),
using SQLJ for ease of DML coding.

If the SQLJ code throws a SQLException, it is caught, and a 
CORBA-defined SQLError is thrown. This in turn would be 
propagated back to the client, where it is handled.



Compiling and Running the Example
=================================


UNIX
----

Enter the command 'make all' or simply 'make' in the shell to compile,
load, and deploy the objects, and run the client program.  Other
targets are 'run' and 'clean'.

Make sure that a shell environment variable ORACLE_HOME is set to
point to the home location of the Oracle installation. This is
operating system dependent, so see the Installation documentation that
came with your system for the location. Also, review the README file
for the Oracle database, and the README file for the CORBA/EJB server
(the Oracle8i ORB), for additional up-to-date information.


Windows NT
----------

On Windows NT, run the batch file makeit.bat from a DOS command prompt
to compile, load, and deploy the objects. Run the batch file runit.bat
to run the client program, and see the results.


Make sure that the environment variables %ORACLE_HOME%, %CLASSPATH%,
and %SERVICE% are set appropriately for the DOS command window. You
can set these as either user or system environment variables from the
Control Panel. Double click on System in the Control Panel then on
the Environment tab to set these variables. Start a new DOS window
after setting environment variable values.


See the Installation documentation that came with your Oracle8i system
for the values of these variables. Also, review the README file for
the Oracle database, and the README file for the CORBA/EJB server (the
Oracle8i ORB), for additional up-to-date information.

You can also set an environment variable %JAVA_HOME% to point to the
root of your Java JDK. For example, SET JAVA_HOME=C:\JDK1.1.6.

employee.idl

module employee {
  struct EmployeeInfo {
    wstring name;
    long number;
    double salary; 
  };

  exception SQLError {
    wstring message;
  };

  interface Employee {
    EmployeeInfo getEmployee (in wstring name) raises (SQLError);
    void updateEmployee (in EmployeeInfo name) raises (SQLError);
  };
};

Client.java

import employee.*;

import oracle.aurora.jndi.sess_iiop.ServiceCtx;

import oracle.aurora.jts.client.AuroraTransactionService;

import oracle.aurora.jts.util.*;

import javax.naming.Context;
import javax.naming.InitialContext;

import java.util.Hashtable;

public class Client
{
  public static void main (String[] args) throws Exception {
    if (args.length != 4) {
      System.out.println ("usage: Client serviceURL objectName user password");
      System.exit (1);
    }
    String serviceURL = args [0];
    String objectName = args [1];
    String user = args [2];
    String password = args [3];

    Hashtable env = new Hashtable ();
    env.put (Context.URL_PKG_PREFIXES, "oracle.aurora.jndi");
    env.put (Context.SECURITY_PRINCIPAL, user);
    env.put (Context.SECURITY_CREDENTIALS, password);
    env.put (Context.SECURITY_AUTHENTICATION, ServiceCtx.NON_SSL_LOGIN);
    Context ic = new InitialContext (env);

    AuroraTransactionService.initialize (ic, serviceURL);

    Employee employee = (Employee)ic.lookup (serviceURL + objectName);
    EmployeeInfo info;

    TS.getTS ().getCurrent ().begin ();

    info = employee.getEmployee ("SCOTT");
    System.out.println (info.name + " " + info.number + " " + info.salary);
    info.salary += (info.salary * 10) / 100;
    employee.updateEmployee (info);
    info = employee.getEmployee ("SCOTT");
    System.out.println (info.name + " " + info.number + " " + info.salary);    

    TS.getTS ().getCurrent ().commit (true);
  }
}

employeeServer/EmployeeImpl.sqlj

package employeeServer;

import employee.*;
import java.sql.*;

public class EmployeeImpl 
       extends _EmployeeImplBase {

  public EmployeeInfo getEmployee (String name) throws SQLError {
    try {
      int empno = 0;
      double salary = 0.0;
      #sql { select empno, sal into :empno, :salary from emp
	            where ename = :name };
      return new EmployeeInfo (name, empno, (float)salary);
    } catch (SQLException e) {
      throw new SQLError (e.getMessage ());
    }
  }

  public void updateEmployee (EmployeeInfo employee) throws SQLError {
    try {
      #sql { update emp set ename = :(employee.name), sal = :(employee.salary)
                    where empno = :(employee.number) };
    } catch (SQLException e) {
      throw new SQLError (e.getMessage ());
    }
  }
}

serversideJDBC

readme.txt

Overview
========

The serversideJDBC example shows how to do transaction management for
CORBA server objects from objects themselves, using SQL transaction
control statements in the JDBC calls.


Source files
============

employee.idl
------------

The CORBA IDL for the example.  Defines:

An EmployeeInfo struct
A SQLError exception
An Employee interface, with
  EmployeeInfo getEmployee (in wstring name)
  void updateEmployee (in EmployeeInfo name)
  void commit()

The SQLError exception is used so that SQLException messages can 
be passed back to the client.  


Client.java
-----------

You invoke the client program from a command prompt, and pass it four
arguments, the

   - service URL (service ID, hostname, port, and SID if port is a listener)
   - name of the published server object to lookup and instantiate
   - username
   - password that authenticates the client to the Oracle8i database server

For example:
% java -classpath LIBs Client sess_iiop://localhost:2481:ORCL \
        /test/myEmployee scott tiger


where LIBs is the classpath that must include

$ORACLE_HOME/lib/aurora_client.jar
$ORACLE_HOME/jdbc/lib/classes111.zip
$ORACLE_HOME/lib/vbjorb.jar
$ORACLE_HOME/lib/vbjapp.jar
$JAVA_HOME/lib/classes.zip

The client code performs the following steps:

   - gets the arguments passed on the command line
   - creates a new JNDI Context (InitialContext())
   - looks up the myEmployee CORBA published object on the server
       (this step also authenticates the client using NON_SSL_LOGIN and
        activates the server object)
   - gets and prints information about the employee SCOTT
   - increases SCOTT's salary by 10%
   - updates the EMP table with the new salary by calling the updateEmployee()
        method on the employee object
   - commits the update by invoking employee.commit()

In other words, this client does everything that the ../clientside/Client.java
program did, but does the transaction handling (a commit only) on the server.

The printed output is:

Beginning salary = 3000.0
Final Salary = 3300.0


employeeServer/EmployeeImpl.sqlj
--------------------------------

Implements the Employee interface.  This file implements the two
methods specified in the IDL: getEmployee() and updateEmployee(),
using SQLJ for ease of DML coding.

EmployeeImpl.sqlj also implements a commit() method, that uses JDBC to issue a
SQL COMMIT statement.



Compiling and Running the Example
=================================


UNIX
----

Enter the command 'make all' or simply 'make' in the shell to compile,
load, and deploy the objects, and run the client program.  Other
targets are 'run' and 'clean'.

Make sure that a shell environment variable ORACLE_HOME is set to
point to the home location of the Oracle installation. This is
operating system dependent, so see the Installation documentation that
came with your system for the location. Also, review the README file
for the Oracle database, and the README file for the CORBA/EJB server
(the Oracle8i ORB), for additional up-to-date information.


Windows NT
----------

On Windows NT, run the batch file makeit.bat from a DOS command prompt
to compile, load, and deploy the objects. Run the batch file runit.bat
to run the client program, and see the results.


Make sure that the environment variables %ORACLE_HOME%, %CLASSPATH%,
and %SERVICE% are set appropriately for the DOS command window. You
can set these as either user or system environment variables from the
Control Panel. Double click on System in the Control Panel then on
the Environment tab to set these variables. Start a new DOS window
after setting environment variable values.


See the Installation documentation that came with your Oracle8i system
for the values of these variables. Also, review the README file for
the Oracle database, and the README file for the CORBA/EJB server (the
Oracle8i ORB), for additional up-to-date information.

You can also set an environment variable %JAVA_HOME% to point to the
root of your Java JDK. For example, SET JAVA_HOME=C:\JDK1.1.6.

employee.idl

module employee {
  struct EmployeeInfo {
    wstring name;
    long number;
    double salary; 
  };

  exception SQLError {
    wstring message;
  };

  interface Employee {
    EmployeeInfo getEmployee (in wstring name) raises (SQLError);
    void updateEmployee (in EmployeeInfo name) raises (SQLError);
    void commit () raises (SQLError); 
  };
};

Client.java

import employee.*;

import oracle.aurora.jndi.sess_iiop.ServiceCtx;

import javax.naming.Context;
import javax.naming.InitialContext;
import java.util.Hashtable;

public class Client
{
  public static void main (String[] args) throws Exception {
    if (args.length != 4) {
      System.out.println ("usage: Client serviceURL objectName user password");
      System.exit (1);
    }
    String serviceURL = args [0];
    String objectName = args [1];
    String user = args [2];
    String password = args [3];

    // get the handle to the InitialContext
    Hashtable env = new Hashtable ();
    env.put (Context.URL_PKG_PREFIXES, "oracle.aurora.jndi");
    env.put (Context.SECURITY_PRINCIPAL, user);
    env.put (Context.SECURITY_CREDENTIALS, password);
    env.put (Context.SECURITY_AUTHENTICATION, ServiceCtx.NON_SSL_LOGIN);
    Context ic = new InitialContext (env);

    // This is using Server-side TX services, specifically, JDBC TX:

    // Now, get the handle to the object and it's info
    Employee employee = (Employee)ic.lookup (serviceURL + objectName);
    EmployeeInfo info = employee.getEmployee ("SCOTT");
    System.out.println ("Beginning salary = " + info.salary);

    // do work on the object or it's info
    info.salary += (info.salary * 10) / 100;

    // call update on the server-side
    employee.updateEmployee (info);

    // call commit on the server-side
    employee.commit ();

    System.out.println ("Final Salary = " + info.salary);
  }
}

employeeServer/EmployeeImpl.sqlj

package employeeServer;

import employee.*;
import java.sql.*;

import oracle.aurora.jts.util.*;
import org.omg.CosTransactions.*;

public class EmployeeImpl 
       extends _EmployeeImplBase
{

  public EmployeeInfo getEmployee (String name) throws SQLError {
    try {
      int empno = 0;
      double salary = 0.0;
      #sql { select empno, sal into :empno, :salary from emp
	            where ename = :name };
      return new EmployeeInfo (name, empno, (float)salary);
    } catch (SQLException e) {
      throw new SQLError (e.getMessage ());
    }
  }

  public void updateEmployee (EmployeeInfo employee) throws SQLError {
    try {
      #sql { update emp set ename = :(employee.name), sal = :(employee.salary)
                    where empno = :(employee.number) };
    } catch (SQLException e) {
      throw new SQLError (e.getMessage ());
    }
  }

  public void commit () throws SQLError {
    try {
      #sql { commit };
    } catch (SQLException e) {
      throw new SQLError (e.getMessage ());
    }
  }
}

serversideJTS

readme.txt

Overview
========

The serversideJTS example shows how to do transaction management for
CORBA server objects from the server object, using the XA JTS
methods.

Compare this example with the clientside example, in which all
transaction management is done on the client.

This example also shows a server object that uses SQLJ in its methods.



Source files
============

employee.idl
------------

The CORBA IDL for the example.  Defines:

An EmployeeInfo struct
A SQLError exception
An Employee interface, with
    EmployeeInfo getEmployee(in wstring name)
    EmployeeInfo getEmployeeForUpdate(in wstring name)
    void updateEmployee(in EmployeeInfo name)

The SQLError exception is used so that SQLException messages can 
be passed back to the client.  



Client.java
-----------

You invoke the client program from a command prompt, and pass it four
arguments, the

   - service URL (service ID, hostname, port, and SID if port is a listener)
   - name of the published server object to lookup and instantiate
   - username
   - password that authenticates the client to the Oracle8i database server

For example:
% java -classpath LIBs Client sess_iiop://localhost:2481:ORCL \
        /test/myEmployee scott tiger


where LIBs is the classpath that must include

$ORACLE_HOME/lib/aurora_client.jar
$ORACLE_HOME/jdbc/lib/classes111.zip
$ORACLE_HOME/lib/vbjorb.jar
$ORACLE_HOME/lib/vbjapp.jar
$JAVA_HOME/lib/classes.zip

The client code is almost exactly the same as the code in
../clientside/Client.java, but without the JTS transaction calls.

The client code performs the following steps:

   - gets the arguments passed on the command line
   - creates a new JNDI Context (InitialContext())
   - initializes the Aurora transaction service
   - looks up the myEmployee CORBA published object on the server
       (this step also authenticates the client using NON_SSL_LOGIN and
        activates the server object)
   - gets and prints information about the employee SCOTT
   - decreases SCOTT's salary by 10%
   - updates the EMP table with the new salary by calling the updateEmployee()
        method on the employee object
   - gets and prints the new information

The printed output is:

Beginning salary = 3000.0
Final Salary = 2700.0



employeeServer/EmployeeImpl.sqlj
--------------------------------

Implements the Employee interface.  This file implements the three
methods specified in the IDL: getEmployee(), getEmployeeForUpdate(),
and updateEmployee(), using SQLJ for ease of DML coding.

EmployeeImpl also adds two private methods, commitTrans() and
startTrans(), that perform XA JTS transaction management from the
server.

Note that on the server there is no need to call
AuroraTransactionService.initialize() to initialize the transaction
manager. This is done automatically by the server ORB. 

If the SQLJ code throws a SQLException, it is caught, and a 
CORBA-defined SQLError is thrown. This in turn would be 
propagated back to the client, where it is handled.



Compiling and Running the Example
=================================


UNIX
----

Enter the command 'make all' or simply 'make' in the shell to compile,
load, and deploy the objects, and run the client program.  Other
targets are 'run' and 'clean'.

Make sure that a shell environment variable ORACLE_HOME is set to
point to the home location of the Oracle installation. This is
operating system dependent, so see the Installation documentation that
came with your system for the location. Also, review the README file
for the Oracle database, and the README file for the CORBA/EJB server
(the Oracle8i ORB), for additional up-to-date information.


Windows NT
----------

On Windows NT, run the batch file makeit.bat from a DOS command prompt
to compile, load, and deploy the objects. Run the batch file runit.bat
to run the client program, and see the results.


Make sure that the environment variables %ORACLE_HOME%, %CLASSPATH%,
and %SERVICE% are set appropriately for the DOS command window. You
can set these as either user or system environment variables from the
Control Panel. Double click on System in the Control Panel then on
the Environment tab to set these variables. Start a new DOS window
after setting environment variable values.


See the Installation documentation that came with your Oracle8i system
for the values of these variables. Also, review the README file for
the Oracle database, and the README file for the CORBA/EJB server (the
Oracle8i ORB), for additional up-to-date information.

You can also set an environment variable %JAVA_HOME% to point to the
root of your Java JDK. For example, SET JAVA_HOME=C:\JDK1.1.6.

employee.idl

module employee {
  struct EmployeeInfo {
    wstring name;
    long number;
    double salary; 
  };

  exception SQLError {
    wstring message;
  };

  interface Employee {
    EmployeeInfo getEmployee (in wstring name) raises (SQLError);
    EmployeeInfo getEmployeeForUpdate (in wstring name) raises (SQLError);
    void updateEmployee (in EmployeeInfo name) raises (SQLError);
  };
};

Client.java

import employee.*;

import oracle.aurora.jndi.sess_iiop.ServiceCtx;

import javax.naming.Context;
import javax.naming.InitialContext;
import java.util.Hashtable;

public class Client
{
  public static void main (String[] args) throws Exception {
    if (args.length != 4) {
      System.out.println ("usage: Client serviceURL objectName user password");
      System.exit (1);
    }
    String serviceURL = args [0];
    String objectName = args [1];
    String user = args [2];
    String password = args [3];

    // get the handle to the InitialContext
    Hashtable env = new Hashtable ();
    env.put (Context.URL_PKG_PREFIXES, "oracle.aurora.jndi");
    env.put (Context.SECURITY_PRINCIPAL, user);
    env.put (Context.SECURITY_CREDENTIALS, password);
    env.put (Context.SECURITY_AUTHENTICATION, ServiceCtx.NON_SSL_LOGIN);
    Context ic = new InitialContext (env);

    // This is using Server-side TX services, specifically, JTS/XA TX:

    // get handle to the object and it's info
    Employee employee = (Employee)ic.lookup (serviceURL + objectName);

    // get the info about a specific employee
    EmployeeInfo info = employee.getEmployee ("SCOTT");
    System.out.println ("Beginning salary = " + info.salary);

    // do work on the object or it's info
    info.salary -= (info.salary * 10) / 100;

    // call update on the server-side
    employee.updateEmployee (info);

    System.out.println ("Final Salary = " + info.salary);
  }
}

employeeServer/EmployeeImpl.sqlj

package employeeServer;

import employee.*;
import java.sql.*;

import oracle.aurora.jts.util.*;
import org.omg.CosTransactions.*;

public class EmployeeImpl extends _EmployeeImplBase 
{
  private void startTrans () throws SQLError {
    try {
      TS.getTS ().getCurrent ().begin ();
    } catch (Exception e) {
      throw new SQLError ("begin failed:" + e);
    }
  }

  private void commitTrans () throws SQLError {
    try {
      TS.getTS ().getCurrent ().commit (true);
    } catch (Exception e) {
      throw new SQLError ("commit failed:" + e);
    }
  }
  
  public EmployeeInfo getEmployee (String name) throws SQLError {
    try {
      startTrans ();

      int empno = 0;
      double salary = 0.0;
      #sql { select empno, sal into :empno, :salary from emp
	            where ename = :name };
      return new EmployeeInfo (name, empno, (float)salary);
    } catch (SQLException e) {
      throw new SQLError (e.getMessage ());
    }
  }

  public EmployeeInfo getEmployeeForUpdate (String name) throws SQLError {
    try {
      startTrans ();

      int empno = 0;
      double salary = 0.0;
      #sql { select empno, sal into :empno, :salary from emp
	            where ename = :name for update };
      return new EmployeeInfo (name, empno, (float)salary);
    } catch (SQLException e) {
      throw new SQLError (e.getMessage ());
    }
  }

  public void updateEmployee (EmployeeInfo employee) throws SQLError {
    try {
      #sql { update emp set ename = :(employee.name), sal = :(employee.salary)
                    where empno = :(employee.number) };

      commitTrans ();
    } catch (SQLException e) {
      throw new SQLError (e.getMessage ());
    }
  }
}

serversideLogging

readme.txt

Overview
========

The serversideLoggin example shows how to do transaction management
for CORBA server objects both directly from the client application, as
in the clientside example, but also adds a method in the server object
that suspends the current transaction, starts a new transaction, and
writes some data out to a table. The second transaction is then
committed and the first transaction is resumed.

Finally, in the original transaction context on the client the update
that happened in a server object method is committed, to end the
transaction.


Source files
============

employee.idl
------------

The CORBA IDL for the example.  Defines:

An EmployeeInfo struct
A SQLError exception
An Employee interface, with
    EmployeeInfo getEmployee(in wstring name)
    EmployeeInfo getEmployeeForUpdate(in wstring name)
    void updateEmployee(in EmployeeInfo name)

The SQLError exception is used so that SQLException messages can 
be passed back to the client.  



Client.java
-----------

You invoke the client program from a command prompt, and pass it four
arguments, the

   - service URL (service ID, hostname, port, and SID if port is a listener)
   - name of the published server object to lookup and instantiate
   - username
   - password that authenticates the client to the Oracle8i database server

For example:
% java -classpath LIBs Client sess_iiop://localhost:2481:ORCL \
        /test/myEmployee scott tiger


where LIBs is the classpath that must include

$ORACLE_HOME/lib/aurora_client.jar
$ORACLE_HOME/jdbc/lib/classes111.zip
$ORACLE_HOME/lib/vbjorb.jar
$ORACLE_HOME/lib/vbjapp.jar
$JAVA_HOME/lib/classes.zip

The client code performs the following steps:

   - gets the arguments passed on the command line
   - creates a new JNDI Context (InitialContext())
   - initializes the Aurora transaction service
   - looks up the myEmployee CORBA published object on the server
       (this step also authenticates the client using NON_SSL_LOGIN and
        activates the server object)
   - starts a new transaction: TS.getTS().getCurrent().begin();
   - gets and prints information about the employee SCOTT
   - increases SCOTT's salary by 10%
   - updates the EMP table with the new salary by calling the updateEmployee()
        method on the employee object
   - gets and prints the new information
   - commits the update: TS.getTS().getCurrent().commit(false);

The client application prints:

Beginning salary = 3000.0
End salary = 3300.0


log.sql
-------

This SQL script creates the log_table table that is used by the
EmployeeImpl class to log database updates.



employeeServer/EmployeeImpl.sqlj
--------------------------------

Implements the Employee interface.  This file implements the three
methods specified in the IDL: getEmployee(), getEmployeeForUpdate(),
and updateEmployee() These methods use SQLJ for ease of DML coding.

The class also implements a private method, log(), that is invoked by
the getEmployee() and getEmployeeForUpdate() methods. The log() method
suspends the current transaction, begins a new transaction, and
updates the log_table with information on who did what.

If the SQLJ code throws a SQLException, it is caught, and a
CORBA-defined SQLError is thrown. This in turn is propagated back to
the client, where it is handled.



Compiling and Running the Example
=================================


UNIX
----

Enter the command 'make all' or simply 'make' in the shell to compile,
load, and deploy the objects, and run the client program.  Other
targets are 'run' and 'clean'.

Make sure that a shell environment variable ORACLE_HOME is set to
point to the home location of the Oracle installation. This is
operating system dependent, so see the Installation documentation that
came with your system for the location. Also, review the README file
for the Oracle database, and the README file for the CORBA/EJB server
(the Oracle8i ORB), for additional up-to-date information.


Windows NT
----------

On Windows NT, run the batch file makeit.bat from a DOS command prompt
to compile, load, and deploy the objects. Run the batch file runit.bat
to run the client program, and see the results.


Make sure that the environment variables %ORACLE_HOME%, %CLASSPATH%,
and %SERVICE% are set appropriately for the DOS command window. You
can set these as either user or system environment variables from the
Control Panel. Double click on System in the Control Panel then on
the Environment tab to set these variables. Start a new DOS window
after setting environment variable values.


See the Installation documentation that came with your Oracle8i system
for the values of these variables. Also, review the README file for
the Oracle database, and the README file for the CORBA/EJB server (the
Oracle8i ORB), for additional up-to-date information.

You can also set an environment variable %JAVA_HOME% to point to the
root of your Java JDK. For example, SET JAVA_HOME=C:\JDK1.1.6.

employee.idl

module employee {
  struct EmployeeInfo {
    wstring name;
    long number;
    double salary; 
  };

  exception SQLError {
    wstring message;
  };

  interface Employee {
    EmployeeInfo getEmployee (in wstring name) raises (SQLError);
    EmployeeInfo getEmployeeForUpdate (in wstring name) raises (SQLError);
    void updateEmployee (in EmployeeInfo name) raises (SQLError);
  };
};

Client.java

import employee.*;

import oracle.aurora.jndi.sess_iiop.ServiceCtx;

import oracle.aurora.jts.client.AuroraTransactionService;
import oracle.aurora.jts.util.TS;

import javax.naming.Context;
import javax.naming.InitialContext;
import java.util.Hashtable;

public class Client
{
  public static void main (String[] args) throws Exception {
    if (args.length != 4) {
      System.out.println ("usage: Client serviceURL objectName user password");
      System.exit (1);
    }
    String serviceURL = args [0];
    String objectName = args [1];
    String user = args [2];
    String password = args [3];

    // get an handle to the InitialContext
    Hashtable env = new Hashtable ();
    env.put (Context.URL_PKG_PREFIXES, "oracle.aurora.jndi");
    env.put (Context.SECURITY_PRINCIPAL, user);
    env.put (Context.SECURITY_CREDENTIALS, password);
    env.put (Context.SECURITY_AUTHENTICATION, ServiceCtx.NON_SSL_LOGIN);
    Context ic = new InitialContext (env);

    // get handle to the TX-Factory
    AuroraTransactionService.initialize (ic, serviceURL);

    // create an instance of an object to be modified in the TX
    Employee employee = (Employee)ic.lookup (serviceURL + objectName);
    EmployeeInfo info;

    // start the TX
    TS.getTS ().getCurrent ().begin ();

    // get employee-info filled up in the TX from the server
    info = employee.getEmployeeForUpdate ("SCOTT");
    System.out.println ("Beginning salary = " + info.salary);

    // do work on the object in the TX; e.g. change the info
    info.salary += (info.salary * 10) / 100;

    // update the info in the TX
    employee.updateEmployee (info);

    // get and print the employee and it's info
    info = employee.getEmployee ("SCOTT");
    System.out.println ("End salary = " + info.salary);

    // commit the TX
    TS.getTS ().getCurrent ().commit (true);
  }
}

log.sql

create table log_table (when date, which number, who number, 
			what varchar2(2000));
exit

employeeServer/EmployeeImpl.sqlj

package employeeServer;

import employee.*;
import oracle.aurora.AuroraServices.ActivatableObject;
import java.sql.*;

import oracle.aurora.rdbms.DbmsJava;
import oracle.aurora.rdbms.Schema;

import oracle.aurora.jts.util.*;
import org.omg.CosTransactions.*;

public class EmployeeImpl 
       extends _EmployeeImplBase 
       implements ActivatableObject 
{
  public EmployeeInfo getEmployee (String name) throws SQLError {
    try {
      int empno = 0;
      double salary = 0.0;
      log ("getEmployee (" + name + ")");
      #sql { select empno, sal into :empno, :salary from emp
	            where ename = :name };
      return new EmployeeInfo (name, empno, (float)salary);
    } catch (SQLException e) {
      throw new SQLError (e.getMessage ());
    }
  }

  public EmployeeInfo getEmployeeForUpdate (String name) throws SQLError {
    try {
      int empno = 0;
      double salary = 0.0;
      log ("getEmployeeForUpdate (" + name + ")");
      #sql { select empno, sal into :empno, :salary from emp
	            where ename = :name for update };
      return new EmployeeInfo (name, empno, (float)salary);
    } catch (SQLException e) {
      throw new SQLError (e.getMessage ());
    }
  }

  public void updateEmployee (EmployeeInfo employee) throws SQLError {
    log ("updateEmployee (" + employee + ")");
    try {
      #sql { update emp set ename = :(employee.name), sal = :(employee.salary)
                    where empno = :(employee.number) };
    } catch (SQLException e) {
      throw new SQLError (e.getMessage ());
    }
  }

  private void log (String message) throws SQLError {
    try {
      // Get the current TX and suspendTxn it
      Control c = TS.getTS ().getCurrent ().suspend ();

      // Start a new transaction
      TS.getTS ().getCurrent ().begin ();

      // Get the current user name
      int ownerNumber = Schema.currentSchema ().ownerNumber ();

      // Get the session-id
      int sessID = DbmsJava.sessionID (DbmsJava.USER_SESSION);

      // Insert the information in the log table
      #sql { insert into log_table (who, which, when, what) 
                    values (:ownerNumber, :sessID, sysdate, :message) };

      // Commit the TX started for logging the info
      TS.getTS ().getCurrent ().commit (true);

      // Resume the suspended TX
      TS.getTS ().getCurrent ().resume (c);
    } catch (Exception e) {
      throw new SQLError (e.toString ());
    }
  }

  public org.omg.CORBA.Object _initializeAuroraObject () {
    return this;
  }
}

multiSessions

readme.txt

Overview
========


Source files
============

employee.idl
------------


Client.java
-----------

You invoke the client program from a command prompt, and pass it five
arguments, the

   - service URL (service ID, hostname, port, and SID if port is a listener)
   - name of the published server object to lookup and instantiate
   - username
   - password that authenticates the client to the Oracle8i database server
   - number of new threads/sessions to create

For example:
% java -classpath LIBs Client sess_iiop://localhost:2481:ORCL \
        /test/myEmployee scott tiger 3

where LIBs is the classpath that must include

$ORACLE_HOME/lib/aurora_client.jar
$ORACLE_HOME/jdbc/lib/classes111.zip
$ORACLE_HOME/lib/vbjorb.jar
$ORACLE_HOME/lib/vbjapp.jar
$JAVA_HOME/lib/classes.zip

The client code performs the following steps:

   - gets the arguments passed on the command line
   - creates a new JNDI Context (InitialContext())
   - in a for-loop, creates different sessions using the ClientThread
     class, and prints out information about the session ID

The printed output from Client should be something like this:

Starting ClientThread (:session0)
Starting ClientThread (:session1)
Beginning salary = 3630.0  in :session0
10% Increase:session0
End salary = 3993.0  in :session0
Starting ClientThread (:session2)
Beginning salary = 3993.0  in :session2
30% Decrease:session2
End salary = 2795.10009765625  in :session2
Beginning salary = 2795.10009765625  in :session1
20% Increase:session1
End salary = 3354.1201171875  in :session1

The actual output will differ depending on the state of the EMP table
when the example is run.


ClientThread.java
-----------------

The ClientThread constructor creates a new named session in the server, and
authenticates the client with NON_SSL_LOGIN, using the Context, service URL,
published object name, username, and password passed as parameters.
(NON_SSL_LOGIN is specified in the Context passed from Client.java.)

The implementation of run() first yields to any other running threads. When
run, it then initializes its transaction context, activates an Employee object
in its session, and starts a new transaction.

It then selects for update the SCOTT row in the EMP table, by calling a method
on the employee object, and updates SCOTT's salary in a way dependent on the
name of the session (this is a Dilbert world).

Finally, it prints the new salary information, and commits the update (thus
unlocking the EMP table row).



employeeServer/EmployeeImpl.sqlj
--------------------------------

Implements the Employee interface.  This file implements the two methods
specified in the IDL: getEmployee(), getEmployeeForUpdate(), and
updateEmployee(), using SQLJ for ease of DML coding.

See the description of this file in ../clientside/employeeServer for more 
information.



Compiling and Running the Example
=================================

UNIX
----

Enter the command 'make all' or simply 'make' in the shell to compile,
load, and deploy the objects, and run the client program.  Other
targets are 'run' and 'clean'.

Make sure that a shell environment variable ORACLE_HOME is set to
point to the home location of the Oracle installation. This is
operating system dependent, so see the Installation documentation that
came with your system for the location. Also, review the README file
for the Oracle database, and the README file for the CORBA/EJB server
(the Oracle8i ORB), for additional up-to-date information.


Windows NT
----------

On Windows NT, run the batch file makeit.bat from a DOS command prompt
to compile, load, and deploy the objects. Run the batch file runit.bat
to run the client program, and see the results.


Make sure that the environment variables %ORACLE_HOME%, %CLASSPATH%,
and %SERVICE% are set appropriately for the DOS command window. You
can set these as either user or system environment variables from the
Control Panel. Double click on System in the Control Panel then on
the Environment tab to set these variables. Start a new DOS window
after setting environment variable values.


See the Installation documentation that came with your Oracle8i system
for the values of these variables. Also, review the README file for
the Oracle database, and the README file for the CORBA/EJB server (the
Oracle8i ORB), for additional up-to-date information.

You can also set an environment variable %JAVA_HOME% to point to the
root of your Java JDK. For example, SET JAVA_HOME=C:\JDK1.1.6.

employee.idl

module employee {
  struct EmployeeInfo {
    wstring name;
    long number;
    double salary; 
  };

  exception SQLError {
    wstring message;
  };

  interface Employee {
    EmployeeInfo getEmployee (in wstring name) raises (SQLError);
    EmployeeInfo getEmployeeForUpdate (in wstring name) raises (SQLError);
    void updateEmployee (in EmployeeInfo name) raises (SQLError);
  };
};

Client.java

import employee.*;

import javax.naming.Context;
import javax.naming.InitialContext;
import java.util.Hashtable;

public class Client
{
  public static void main (String[] args) throws Exception {
    if (args.length != 5) {
      System.out.println ("usage: Client serviceURL objectName user password "
			  + "sessionsCount");
      System.exit (1);
    }
    String serviceURL = args [0];
    String objectName = args [1];
    String user = args [2];
    String password = args [3];
    int sessionCount = Integer.parseInt (args[4]);

    // get the handle to InitialContext
    // Note: authentication is done per session in ClientThread
    Hashtable env = new Hashtable ();
    env.put (Context.URL_PKG_PREFIXES, "oracle.aurora.jndi");
    Context ic = new InitialContext (env);

    // invoke different sessions using ClientThread
    for (int i = 0; i < sessionCount; i++) {
      String sessionName = new String (":session" + i);
      ClientThread ct =
	new ClientThread (ic, serviceURL, objectName, sessionName,
			  user, password);
      System.out.println ("Starting ClientThread (" + sessionName + ")");
      ct.start ();
    }
  }
}

ClientThread.java

import employee.*;

import oracle.aurora.jts.client.AuroraTransactionService;
import oracle.aurora.jndi.sess_iiop.ServiceCtx;
import oracle.aurora.jndi.sess_iiop.SessionCtx;
import oracle.aurora.AuroraServices.LoginServer;
import oracle.aurora.client.Login;
import oracle.aurora.jts.util.TS;

import javax.naming.Context;
import javax.naming.InitialContext;
import java.util.Hashtable;

public class ClientThread extends Thread
{
  private Context ic = null;
  private String serviceURL = null;
  private String objectName = null;
  private String sessionName = null;
  private SessionCtx session = null;

  public ClientThread () {}

  public ClientThread (Context ic, String serviceURL, String objectName,
		       String sessionName, String user, String password)
  {
    try {
      this.ic = ic;
      ServiceCtx service = (ServiceCtx)ic.lookup (serviceURL);
      this.session = (SessionCtx)service.createSubcontext (sessionName);

      LoginServer login_server = (LoginServer)session.activate ("etc/login");
      Login login = new Login (login_server);
      login.authenticate (user, password, null);
      
      this.serviceURL = serviceURL;
      this.sessionName = sessionName;
      this.objectName = objectName;
    } catch (Exception e) {
      e.printStackTrace ();
    }
  }

  public void run () {
    try {
      this.yield ();

      // Get handle to the TX-Factory
      AuroraTransactionService.initialize (ic, serviceURL + "/" + sessionName);

      // create an instance of an employee object in the session
      Employee employee = (Employee)session.activate (objectName);
      EmployeeInfo info;

      // start the transaction
      TS.getTS ().getCurrent ().begin ();

      // Get the info about an employee 
      // Note: lock is set on the row using 'for update' clause
      // while select operation
      info = employee.getEmployeeForUpdate ("SCOTT");
      System.out.println ("Beginning salary = " + info.salary +
			  "  in " + sessionName);

      // arbitrarily change the value of the salary, 
      // e.g. depending on sessionName
      if (sessionName.endsWith("0")) {
	System.out.println ("10% Increase" + sessionName);
	info.salary += (info.salary * 10) / 100;
      } else if (sessionName.endsWith("1")) {
	System.out.println ("20% Increase" + sessionName);
	info.salary += (info.salary * 20) / 100;
      } else {
	System.out.println ("30% Decrease" + sessionName);
	info.salary -= (info.salary * 30) / 100;
      }

      // Try sleeping this thread for a while before updating the info
      // Note: the other threads MUST wait 
      // (since selected with 'for update' clause)
      this.sleep (2000);

      // update the infomation in the transaction
      employee.updateEmployee (info);

      // Get and print the info in the transaction
      // Note: do NOT use 'for update' here
      info = employee.getEmployee ("SCOTT");
      System.out.println ("End salary = " + info.salary + "  in " +
			  sessionName);

      // commit the changes
      TS.getTS ().getCurrent ().commit (true);

    } catch (Exception e) {
      e.printStackTrace ();
    }
  }
}

employeeServer/EmployeeImpl.sqlj

package employeeServer;

import employee.*;
import oracle.aurora.AuroraServices.ActivatableObject;
import java.sql.*;

import oracle.aurora.jts.util.*;
import org.omg.CosTransactions.*;

public class EmployeeImpl 
       extends _EmployeeImplBase 
       implements ActivatableObject 
{
  public EmployeeInfo getEmployee (String name) throws SQLError {
    try {
      int empno = 0;
      double salary = 0.0;
      #sql { select empno, sal into :empno, :salary from emp
  	            where ename = :name };
      return new EmployeeInfo (name, empno, (float)salary);
    } catch (SQLException e) {
      throw new SQLError (e.getMessage ());
    }
  }

  public EmployeeInfo getEmployeeForUpdate (String name) throws SQLError {
    try {
      int empno = 0;
      double salary = 0.0;
      #sql { select empno, sal into :empno, :salary from emp
	            where ename = :name for update };
      return new EmployeeInfo (name, empno, (float)salary);
    } catch (SQLException e) {
      throw new SQLError (e.getMessage ());
    }
  }

  public void updateEmployee (EmployeeInfo employee) throws SQLError {
    try {
      #sql { update emp set ename = :(employee.name), sal = :(employee.salary)
                    where empno = :(employee.number) };
    } catch (SQLException e) {
      throw new SQLError (e.getMessage ());
    }
  }

  public org.omg.CORBA.Object _initializeAuroraObject () {
    return this;
  }
}




Prev

Top

Next
Oracle
Copyright © 1999 Oracle Corporation.

All Rights Reserved.

Library

Product

Contents

Index