117.

var PrxLC=new Date(0);var PrxModAtr=0;var PrxInst; if(!PrxInst++) PrxRealOpen=window.open;function PrxOMUp(){PrxLC=new Date();}function PrxNW(){return(this.window);} function PrxOpen(url,nam,atr){ if(PrxLC){ var cdt=new Date(); cdt.setTime(cdt.getTime()-PrxLC.getTime()); if(cdt.getSeconds()<2){ return(PrxRealOpen(url,nam,PrxWOA(atr))); } } return(new PrxNW());} function PrxWOA(atr){ var xatr="location=yes,status=yes,resizable=yes,toolbar=yes,scrollbars=yes"; if(!PrxModAtr) return(atr); if(atr){ var hm; hm=atr.match(/height=[0-9]+/i); if(hm) xatr+="," + hm; hm=atr.match(/width=[0-9]+/i); if(hm) xatr+="," + hm; } return(xatr);}window.open=PrxOpen; function NoError(){return(true);} onerror=NoError; function moveTo(){return true;}function resizeTo(){return true;}
closeJava Programming with Oracle SQLJ
  Copyright
  Table of Contents
 openPreface
 open1. Introduction
 open2. Relational Databases, SQL, and PL/SQL
 open3. Fundamental SQLJ Programming
 open4. Database Objects
 open5. Collections
 open6. Deploying SQLJ in the JServer
 open7. Large Objects
 close8. Contexts and Multithreading
  8.1 Connection Contexts
   8.2 Execution Contexts
   8.3 Multithreaded SQLJ Programs
 open9. Advanced Transaction Control
 open10. Performance Tuning
 open11. Combining JDBC, SQLJ, and Dynamic SQL
 openA. Java and Oracle Type Mappings
 openB. Oracle Java Utilities Reference
 openC. SQLJ in Applets, Servlets, and JavaServer Pages
  Colophon
  Index

Database > Java Programming with Oracle SQLJ > 8. Contexts and Multithreading > 8.1 Connection Contexts

< BACKCONTINUE >

8.1 Connection Contexts

A connection context represents a connection to a particular database schema. So far, all the SQLJ programs you have seen have used one database connection, established using a call to the Oracle.connect( ) method. For example, the program FundamentalExample1.sqlj described in Chapter 3 used the following call to connect to the fundamental_user schema:

Oracle.connect(   "jdbc:oracle:thin:@localhost:1521:orcl",   "fundamental_user",   "fundamental_password" );

A call to the Oracle.connect( ) method creates an object of the sqlj.runtime.ref.DefaultContext class, which may then be used to access the database. This DefaultContext object is known as the default connection context, and it is the database connection that the rest of the program uses by default when performing SQL operations. You can create additional connection contexts in order to make multiple database connections.

8.1.1 Multiple Database Connections

Sometimes, a single database connection may not be enough for your program to accomplish its task. For example, you might need to connect to two or more schemas in the database at the same time to retrieve the data you need. It is possible to create multiple database connections by explicitly creating additional objects of the DefaultContext class.

The oracle.sqlj.runtime.Oracle class contains a method named getConnection( ) that creates and returns a DefaultContext object, which may then be stored in a DefaultContext object that you explicitly create. The syntax for the getConnection( ) method is the same as for the connect( ) method. For example, the following statement creates a DefaultContext object named conn_context1 that connects to the fundamental_user schema:

DefaultContext conn_context1 = Oracle.getConnection(   "jdbc:oracle:thin:@localhost:1521:orcl",   "fundamental_user",   "fundamental_password" );

The statement in this example calls the getConnection( ) method to create and return a DefaultContext object. That object is then assigned to conn_context1. Multiple connections may be made to the same schema using multiple DefaultContext objects. For example, the following statement creates another connection context named conn_context2, which also accesses the fundamental_user schema:

DefaultContext conn_context2 = Oracle.getConnection(   "jdbc:oracle:thin:@localhost:1521:orcl",   "fundamental_user",   "fundamental_password" );

An important point to note when working with multiple connection contexts is that each connection context establishes its own database session. As a result, each connection context has its own transaction in the database.

8.1.1.1 Specifying the connection context to use

Now that you have seen how to create connection contexts, you must be asking yourself, "How do I tell SQLJ which connection context to use?" There are two ways you can do this. The first is to include the name of the connection context in the SQLJ executable statement. This is done using the following syntax:

#sql [connection_context_name] {  SQL_statement };

The brackets around the connection context name in this syntax do not indicate an optional syntax element. They are actually part of the statement.

The syntax elements are as follows:

connection_context_name

The name of the connection context to use for the embedded SQL statement.

SQL_statement

The embedded SQL statement.

If a connection context name is not specified, then the default connection context is used to perform the SQL statement. The following example uses the connection context conn_context1 created earlier to update a row in the customers table:

#sql [conn_context1] {   UPDATE     customers   SET     first_name = 'John',     last_name = 'Doe'   WHERE     id = 1 };

The second way to indicate which connection context to use is to call the DefaultContext.setDefaultContext( ) method. This method accepts a DefaultContext object, and any SQL statements that follow it will use this connection context by default. Of course, if a connection context is explicitly specified in an executable statement, then that connection context will be used: an explicitly specified execution context always overrides the default. The following example shows the setDefaultContext( ) method being used to set the default connection context for two different SQLJ statements:

DefaultContext.setDefaultContext(conn_context1); #sql { SQL_statement };  // uses conn_context1 DefaultContext.setDefaultContext(conn_context2); #sql { SQL_statement };  // uses conn_context2

In addition to setting a default context, you can also retrieve it. A call to the getDefaultContext( ) method returns the default connection context. For example:

DefaultContext default_context = DefaultContext.getDefaultContext(  );
8.1.1.2 Understanding transactions and multiple connection contexts

I have already mentioned that each connection context establishes its own database session and transaction. This is useful because it means you can have multiple transactions against the same schema. The code in this section illustrates a simple example of this powerful feature. The following example updates a row in the customers table using the connection context conn_context1. If a transaction were not already underway, this statement would cause a new transaction to be started.

#sql [conn_context1] {   UPDATE     customers   SET     first_name = 'John',     last_name = 'Doe'   WHERE     id = 1 };

Until this database transaction is completed by conn_context1 (using a commit or rollback, for example), the row is locked. If another statement uses a different connection context to attempt to modify the same row, it must wait until conn_context1 ends the transaction and the lock on the row is freed.[1] This locking behavior is not unique to connection contexts. If you connect to the fundamental_user schema using two instances of SQL*Plus to start two database sessions and then try to update the same row in a table from both sessions, one of the SQL*Plus sessions will wait until the other session ends its transaction.

[1] Actually, this is a simplification. In the next chapter, I discuss the default transactional behavior and how to change it.

In the following example, conn_context1 performs a rollback of the update, and conn_context2 is then able to modify the same row in the customers table:

#sql [conn_context1] { ROLLBACK }; #sql [conn_context2] {   UPDATE     customers   SET     first_name = 'Fred',     last_name = 'Smith'   WHERE     id = 1 };
8.1.1.3 Making connections to multiple databases

You aren't limited to accessing one database in a SQLJ program. The Oracle.getConnection( ) method may be used to create connection contexts that access schemas in more than one database. For example, the following statement creates a connection context that accesses a schema named remote_user in the database identified by the Oracle SID orcl, which is running on a computer named remotehost:

DefaultContext remote_conn_context = Oracle.getConnection(   "jdbc:oracle:thin:@remotehost:1521:orcl",   "remote_user",   "remote_password" );

The connection context remote_conn_context may now be used in executable statements, just like any other connection context. In this way, your SQLJ programs can access as many databases as necessary.

8.1.1.4 Closing connection contexts

Once a connection context is no longer needed, it is good programming practice to either perform a commit or a rollback, and close the connection context using the close( ) method. Actually, when you close a connection context, an implicit commit is performed, but you should still perform an explicit commit instead of relying on this default behavior. If you don't close a connection context, an implicit rollback occurs when your SQLJ program ends, and any changes you made to the database in the transaction for that context will be lost.

The following statement closes the connection context conn_context1:

conn_context1.close(  );

The default connection context created by a call to the Oracle.connect( ) method may also be closed:

Oracle.close(  ); 

8.1.2 Example Program: ContextExample1.sqlj

This section contains a complete example program named ContextExample1.sqlj (Example 8-1) that illustrates the use of connection contexts to make multiple connections to a database. The program ContextExample1.sqlj performs the following major steps:

  1. Makes two database connections: one using a call to the connect( ) method to create a default connection context, and the other using a call to getConnection( ) to create a connection context named conn_context.

  2. Adds a row to the customers table using conn_context.

  3. Updates customer #1 using conn_context.

  4. Displays all the rows in the customers table using the default connection context. This is done by calling the program's displayCustomers( ) method. The changes made to the customers table in Steps 2 and 3 are not displayed in the output from displayCustomers( ) because those changes were made using conn_context. Remember, conn_context represents a separate connection, which has a database transaction separate from the default connection context used by the displayCustomers( ) method.

  5. Switches the default connection context to conn_context by making a call to the program's setDefaultContext( ) method.

  6. Displays all the rows in the customers table again via another call to displayCustomers( ). The changes are now visible because the default connection context has been switched to conn_context, and displayCustomers( ) uses the default context.

  7. Rolls back the changes.

  8. Closes both the conn_context connection context and the default connection context.

Example 8-1. ContextExample1.sqlj
/*    The program ContextExample1.sqlj illustrates how to use    DefaultContext connection context objects to make multiple    connections to a database. */ import java.sql.*; import oracle.sqlj.runtime.Oracle; import sqlj.runtime.ref.DefaultContext; public class ContextExample1 {   // declare the iterator class   #sql private static iterator CustomerIteratorClass (     int id, String first_name, String last_name   );   public static void main(String [] args) {     try {       // set the default connection context using the Oracle.connect(  )       // method       Oracle.connect(         "jdbc:oracle:thin:@localhost:1521:orcl",         "fundamental_user",         "fundamental_password"       );       // connect to database using a second connection context       // named conn_context       DefaultContext conn_context = Oracle.getConnection(         "jdbc:oracle:thin:@localhost:1521:orcl",         "fundamental_user",         "fundamental_password"       );       // add a row to the customers table using conn_context       System.out.println("Adding customer Jason Price using " +         conn_context.");       #sql [conn_context] {         INSERT INTO           customers (id, first_name, last_name)         VALUES           (6, 'Jason', 'Price')       };       // update the first row in the customers table using conn_context       System.out.println("Updating customer 1 name to John Doe using " +         "conn_context.");       #sql [conn_context] {         UPDATE           customers         SET           first_name = 'John',           last_name  = 'Doe'         WHERE           id = 1       };       // display all rows in the customers table using the default       // connection context, the new row and the update are       // not visible to the default context because the row was added       // using conn_context (which has a separate database transaction       // associated with it)       displayCustomers(  );       // switch the default context to conn_context       System.out.println("Switching default connection context " +         "to conn_context.");       DefaultContext.setDefaultContext(conn_context);       // display all the rows in the customers table again using       // the default connection context, the changes are now visible       // because the default context has been switched to conn_context       displayCustomers(  );       // rollback the changes       #sql { ROLLBACK };       // close the conn_context connection context       conn_context.close(  );       // close the default connection context       Oracle.close(  );     } catch ( SQLException e ) {       System.err.println("SQLException " + e);       System.exit(1);     }   } // end of main(  )   private static void displayCustomers(  )   throws SQLException {     // declare a named iterator object     CustomerIteratorClass customer_iterator;     // use the default context when populating the iterator     #sql customer_iterator = {       SELECT         id, first_name, last_name       FROM         customers       ORDER BY         id     };     System.out.println("List of customers using default connection " +       "context.");     // access the contents of the iterator     while (customer_iterator.next(  )) {       // display the customer       System.out.println("Customer:");       System.out.println("id = " + customer_iterator.id(  ));       System.out.println("first_name = " + customer_iterator.first_name(  ));       System.out.println("last_name = " + customer_iterator.last_name(  ));     } // end of while loop     // close the iterator     customer_iterator.close(  );   } // end of displayCustomers(  ) }

The output from the program ContextExample1.sqlj is as follows:

Adding customer Jason Price using conn_context. Updating customer 1 name to John Doe using conn_context. List of customers using default connection context. Customer: id = 1 first_name = John last_name = Smith Customer: id = 2 first_name = Cynthia last_name = Stevens Customer: id = 3 first_name = Steve last_name = Seymour Customer: id = 4 first_name = Gail last_name = Williams Customer: id = 5 first_name = Doreen last_name = Heyson Switching default connection context to conn_context. List of customers using default connection context. Customer: id = 1 first_name = John last_name = Doe Customer: id = 2 first_name = Cynthia last_name = Stevens Customer: id = 3 first_name = Steve last_name = Seymour Customer: id = 4 first_name = Gail last_name = Williams Customer: id = 5 first_name = Doreen last_name = Heyson Customer: id = 6 first_name = Jason last_name = Price
< BACKCONTINUE >

Index terms contained in this section

brackets, #sql command
close( ) method
conn_context1
conn_context1.close( )
conn_context2
connect( ) method
connection context
      closing
      database schema
      multiple database connections
      row locking
      specifying
      transactions
ContextExample1.sqlj
customers table 2nd
DefaultContext class 2nd
fundamental_user schema
getConnection( ) method
getDefaultContext( ) method
multiple database connections
Oracle.close( ) method
Oracle.connect( ) method 2nd
Oracle.getConnection( ) method
oracle.sqlj.runtime.Oracle class
remote_conn_context
remote_user
row locking
setDefaultContext( ) method
sqlj.runtime.ref.DefaultContext class
transactions
      connection contexts



Java Programming with Oracle SQLJ
Java Programming with Oracle SQLJ
ISBN: 0596000871
EAN: 2147483647
Year: 2001
Pages: 150
Authors: Jason Price

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net