Oracle8i CORBA Developer's Guide and Reference Release 3 (8.1.7) Part Number A83722-01 |
|
For JTA, client-side demarcated transactions are explicitly demarcated programmatically through the UserTransaction
object, which must be bound with the bindut
command into the namespace. With client-side transaction demarcation, the client controls the transaction. The client starts a global transaction by invoking the UserTransaction begin
method; it ends the transaction by invoking either the commit
or rollback
methods.
In addition, the client must always set up an environment including a Hashtable
with authentication information and namespace location URL. It must also register an OracleDriver
when retrieving the transaction objects from the namespace.
Figure 7-3 shows a client invoking a server object. The client starts a global transaction, then invokes the object. The transactional context is propagated to include the server object.
The following must occur for the client to demarcate the transaction:
Hashtable
environment with the namespace address and authentication information.
OracleDriver
.
UserTransaction
object from the namespace within the client logic. When you retrieve the UserTransaction
object from any client, the URL must consist of "jdbc_access://
" prefix before the JNDI name.
UserTransaction.begin()
.
UserTransaction.commit()
or UserTransaction.rollback()
.
Example 7-2 shows a client that invokes a server object within the transaction.
After binding the UserTransaction
object, your client code can retrieve the UserTransaction
object and start a global transaction. Since the client is retrieving the UserTransaction
object from a remote site, the lookup requires authentication information, location of the namespace, the OracleDriver
registration, and the "jdbc_access://
" prefix.
import employee.*; import java.sql.DriverManager; import java.util.Hashtable; import javax.naming.Context; import javax.naming.InitialContext; import javax.transaction.UserTransaction; import java.sql.SQLException; import javax.naming.NamingException; import oracle.aurora.jndi.jdbc_access.jdbc_accessURLContextFactory; import oracle.aurora.jndi.sess_iiop.ServiceCtx; public class Client { public static void main (String[] args) throws Exception { UserTransaction ut = null; EmployeeInfo info; String sessiiopURL = args [0]; String objectName = args [1]; //Set up the service URL to where the UserTransaction object //is bound. Since from the client, the connection to the database //where the namespace is located can be communicated with over either //a Thin or OCI8 JDBC driver. This example uses a Thin JDBC driver.String namespaceURL = "jdbc:oracle:thin:@nsHost:1521:ORCL";
// lookup usertransaction object in the namespace try {//1.(a) Authenticate to the database.
// create InitialContext and initialize for authenticating client Hashtable env = new Hashtable (); env.put (Context.URL_PKG_PREFIXES, "oracle.aurora.jndi"); env.put (Context.SECURITY_PRINCIPAL, "SCOTT"); env.put (Context.SECURITY_CREDENTIALS, "TIGER"); env.put (Context.SECURITY_AUTHENTICATION, ServiceCtx.NON_SSL_LOGIN);//1.(b) Specify the location of the namespace where the transaction objects
// are bound.
env.put(jdbc_accessURLContextFactory.CONNECTION_URL_PROP, namespaceURL);
Context ic = new InitialContext (env);//2. Register a JDBC OracleDriver.
Required for JDBC connection to retrieve // UserTransaction from namespace.DriverManager.registerDriver (new oracle.jdbc.driver.OracleDriver());
//3. Retrieve the UserTransaction object from JNDI namespace
ut = (UserTransaction)ic.lookup ("jdbc_access://test/myUT");
//4. Start the transaction
ut.begin();
//5. Retrieve the server object reference
// lookup employee object in the namespace Employee employee = (Employee)ic.lookup
("sess_iiop://myhost:1521:orcl/test/employee");//6. Perform bean business logic.
// retrieve the info info = employee.getEmployee ("SCOTT"); System.out.println ("Before Update: " + info.name +" " + info.salary); // change the salary and update it System.out.println ("Increase by 10%"); info.salary += (info.salary * 10) / 100; employee.updateEmployee (info);//7. End the transaction
//Commit the updated value ut.commit (); }
The transaction context is propagated to the object when the client invokes it.
The previous example showed how a transaction context was propagated to server objects from a client within the JTA global transaction. When you execute the server object, the transaction is propagated over the IIOP transport layer. In addition to invoking IIOP server objects, you may wish to update databases over JDBC connections. The databases that the object accesses must be enlisted to be included within the global transaction.
If you access an Oracle8i database from the server that should be included in the transaction, you must open the connection to the database after the global transaction starts.
This section shows how you enlist databases using a JDBC connection in tandem with the IIOP server object propagation.
To include a remote database within the transaction from a client, you must use a DataSource
object, which has been bound in the namespace as a JTA DataSource
. Then, invoke the getConnection
method of the DataSource
object after the transaction has started, and the database is included in the global transaction.
The following must occur in the client runtime to demarcate the transaction:
Hashtable
environment with the namespace address and authentication information.
OracleDriver
.
UserTransaction
object from the namespace within the client logic. When you retrieve the UserTransaction
object from the client, the URL must consist of "jdbc_access://
" prefix before the JNDI name.
UserTransaction.begin()
.
UserTransaction.commit()
or UserTransaction.rollback()
.
Example 7-3 shows a client that invokes a server object and enlists a single database within the transaction.
Before starting the client, you must first bind the UserTransaction
and DataSource
objects in the namespace. The following example follows the steps listed in "JTA Client-Side Demarcation Including Databases".
import employee.*; import java.sql.DriverManager; import java.util.Hashtable; import javax.naming.Context; import javax.naming.InitialContext; import javax.transaction.UserTransaction; import java.sql.SQLException; import javax.naming.NamingException; import oracle.aurora.jndi.jdbc_access.jdbc_accessURLContextFactory; import oracle.aurora.jndi.sess_iiop.ServiceCtx; public class Client { public static void main (String[] args) throws Exception { UserTransaction ut = null; EmployeeInfo info; String sessiiopURL = args [0]; String objectName = args [1]; String dsName = args [2]; //Set up the service URL to where the UserTransaction object //is bound. Since from the client, the connection to the database //where the namespace is located can be communicated with over either //a Thin or OCI8 JDBC driver. This example uses a Thin JDBC driver.String namespaceURL = "jdbc:oracle:thin:@nsHost:1521:ORCL";
// lookup usertransaction object in the namespace try {//1.(a) Authenticate to the database.
// create InitialContext and initialize for authenticating client Hashtable env = new Hashtable (); env.put (Context.URL_PKG_PREFIXES, "oracle.aurora.jndi"); env.put (Context.SECURITY_PRINCIPAL, "SCOTT"); env.put (Context.SECURITY_CREDENTIALS, "TIGER"); env.put (Context.SECURITY_AUTHENTICATION, ServiceCtx.NON_SSL_LOGIN);//1.(b) Specify the location of the namespace where the transaction objects
// are bound.
env.put(jdbc_accessURLContextFactory.CONNECTION_URL_PROP, namespaceURL);
Context ic = new InitialContext (env);//2. Register a JDBC OracleDriver.
This is a requirement for retrieving
// the UserTransaction and DataSource objects from the namespace over // a JDBC connection.DriverManager.registerDriver (new oracle.jdbc.driver.OracleDriver());
//3. Retrieve the UserTransaction object from JNDI namespace
ut = (UserTransaction)ic.lookup ("jdbc_access://test/myUT");
//4. Start the transaction
ut.begin();
//5.(a) Retrieve the DataSource
(that was previously bound with bindds in // the namespace. After retrieving the DataSource... // get a connection to a database. You need to provide authentication info // for a remote database lookup, similar to what you would do from a client. // In addition, if this was a two-phase commit transaction, you must provide // the username and password.DataSource ds = (DataSource)ic.lookup ("jdbc_access://test/empDB");
//5.(b). Get connection to the database
through DataSource.getConnection // in this case, the database requires the same username and password as // set in the environment.Connection conn = ds.getConnection ();
//6. Retrieve the server object reference
// lookup employee object in the namespace Employee employee = (Employee)ic.lookup (sessiiopURL + objectName);//7 (a). Perform bean business logic.
// retrieve the info info = employee.getEmployee ("SCOTT"); System.out.println ("Before Update: " + info.name +" " + info.salary); // change the salary and update it System.out.println ("Increase by 10%"); info.salary += (info.salary * 10) / 100; employee.updateEmployee (info);//7 (b). Execute SQL
statements against the enlisted database. Statement stmt = conn.createStatement (); int cnt = stmt.executeUpdate ("insert into my_tab values (39304)");//8. Close the database connection.
conn.close ();//9. End the transaction
//Commit the updated value ut.commit (); }
|
Copyright © 1996-2000, Oracle Corporation. All Rights Reserved. |
|