ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Java Programming with Oracle SQLJ: Contexts and Multithreading
Pages: 1, 2, 3, 4, 5

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.

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.

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 };

TIP: 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( );

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. (Actually, this is a simplification. In the next chapter, I discuss the default transactional behavior and how to change it.) 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.

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
};

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.

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(  );

Pages: 1, 2, 3, 4, 5

Next Pagearrow