BEA Logo BEA WebLogic Server Release 5.0

  Corporate Info  |  News  |  Solutions  |  Products  |  Partners  |  Services  |  Events  |  Download  |  How To Buy

Using WebLogic JDBC

I. Introduction
Overview of WebLogic JDBC
Setting classpath when starting WebLogic Server
WebLogic JDBC architecture
Using third-party JDBC 2.0 drivers in a multitier configuration

II. The WebLogic JDBC API
WebLogic JDBC API reference
Overview of WebLogic JDBC objects and their classes
Upgrading to JDK 1.1

III. Implementing with WebLogic JDBC
Importing packages
Creating the Client
Using an explicit or an embedded T3Client
Setting properties for connecting
Properties to be set for the two-tier connection
Properties to be set for the multitier connection
Using a URL to set WebLogic JDBC properties
Setting up an embedded T3Client
Connecting to the DBMS
Using a named, cached JDBC Connection
Using connection pools
Creating a startup connection pool
Creating a dynamic connection pool
Obtaining a connection from a connection pool
Using Connection Pools with Server-side Applications
Managing connection pools
Inserting, updating, and deleting records
Creating and using stored procedures and functions
Disconnecting the T3Client
Code summary

Other WebLogic JDBC features
Waiting on Oracle resources
Extended SQL
Oracle array fetches
Multibyte character set support
About WebLogic JDBC and Oracle NUMBER columns

IV. Implementing with WebLogic JDBC and the JDBC-ODBC bridge
Importing packages
Creating the T3Client
Connecting
Accessing data
Exception handling
Disconnecting and closing objects
Code summary

V. Change history

Other related documents
Installing WebLogic (nonWindows)
Installing WebLogic (Windows)
Developers Guides
API Reference Manual
Using the jdbcKona Type 2 JDBC drivers
Using jdbcKona/Oracle
Using jdbcKona/Sybase and
jdbcKona/MSSQLServer
Using jdbcKona/MSSQLServer4
Using jdbcKona/Informix4
Performance tuning your JDBC application
Troubleshooting JDBC hangs and SEGVs
Glossary
Code examples
WebLogic JDBC examples
Examples for WebLogic JDBC
Examples for WebLogic JDBC and ODBC

Top of the page

I. Introduction

Overview of WebLogic JDBC

WebLogic JDBC, WebLogic's multitierJDBC implementation (based on JavaSoft's JDBC specification), gives applets and applications database access from within WebLogic. WebLogic supports multiple multitier server products that provide various services, one of which is database access with WebLogic JDBC; other WebLogic multitier products offer event notification services (WebLogic Events) and remote computing (WebLogic Remote).

Because WebLogic JDBC is Java-only, that is, it uses no native methods, it can be used for applet programming. Java client applications built with WebLogic JDBC require no client-side database libraries.

A WebLogic JDBC applet or application acts as a client of the WebLogic Server. The WebLogic Server gives a WebLogic JDBC applet or application simultaneous access to multiple heterogeneous databases. In addition to acting as an intermediate server between the DBMS and the client applet/application, WebLogic also provides other server facilities like server-wide logging, client Workspaces, instrumentation, and management.

WebLogic JDBC requires a JDBC driver between the WebLogic Server and the database server. You can use one of the WebLogic two-tier drivers -- jdbcKona/Informix4, jdbcKona/Oracle, jdbcKona/Sybase, jdbcKona/MSSQLServer, and jdbcKona/MSSQLServer4 -- for vendor-specific database access. You may also elect to use any other JDBC driver, including a JDBC driver for ODBC access. If you choose to use a non-WebLogic JDBC driver between the WebLogic Server and the DBMS, we can only offer you support in deploying WebLogic JDBC after you have demonstrated that your two-tier non-WebLogic JDBC driver works satisfactorily in a two-tier environment.

There are some implications in using the WebLogic Server with certain two-tier JDBC drivers. The WebLogic Server is multithreaded, which means that you can have concurrent database operations taking place in different threads. This requires threadsafe DBMS client libraries for the type 2 JDBC drivers. If you are using WebLogic JDBC with jdbcKona/Oracle on Windows NT, for example, you must have the Oracle 7.3 client libraries, which are threadsafe, installed for use with the WebLogic-JDBC-Server-side two-tier driver. The 7.1/7.2 client libraries are not threadsafe. This requirement does not apply when you are using jdbcKona/Oracle in a two-tier environment; it only applies when you use the WebLogic Server with jdbcKona/Oracle in a multitier environment. You can use jdbcKona/Oracle in a two-tier environment (that is, without the WebLogic Server) with any of the Oracle 7.x client libraries, but WebLogic JDBC used with jdbcKona/Oracle and the WebLogic Server on Windows NT in a multitier environment requires the threadsafe Oracle 7.3 client libraries.

Setting classpath when starting WebLogic Server

When you use a two-tier JDBC driver to connect to a database through one of the WebLogic Server's multitier drivers (t3, pool, or jts), you must start the server with the classes of the JDBC driver appended to the WebLogic classpath, specified with the weblogic.class.path property on the command line when starting WebLogic Server.

Please see jdbcKona support for a table of the DBMS versions, client library versions, and operating systems supported by the WebLogic jdbcKona drivers.

Top of the page

WebLogic JDBC architecture

WebLogic JDBC's architecture is defined by its place in the WebLogic framework as part of WebLogic's multitier environment. The WebLogic JDBC Server sits between the WebLogic JDBC application and the remote DBMSes that it accesses. The WebLogic JDBC application is a client of the WebLogic Server, and the WebLogic Server becomes a client of the DBMS. There are two sides to this relationship that are important to understand:

Between the WebLogic Server and its WebLogic JDBC clients. Each WebLogic JDBC client has its own context, or Workspace, within WebLogic. The protocol between the WebLogic Server and its clients is a multiplexed, bidirectional, asynchronous connection. The connection between any T3Client and the WebLogic Server is a "rich-socket connection;" that means that the connection carries much more information than a TCP socket connection does. Internally, the WebLogic Server uses an efficient packet-based queuing protocol. For more information about the relationship between T3Clients and the WebLogic Server, see the Developers Guide, Writing a T3Client application.

Between the WebLogic Server and the DBMS. Using a JDBC driver and vendor libraries, the WebLogic Server maintains a connection to one or more databases on behalf of the T3Client. The WebLogic Server communicates with remote DBMS via JDBC drivers and, depending upon the JDBC driver, a vendor-specific library or ODBC. We talk about this connection between the WebLogic Server and the DBMS as the "two-tier connection." The WebLogic Server may be connected to more than one database for requests from a single client; and the WebLogic Server may be connected to only one database for requests from multiple clients.

There is also a fundamental relationship between a WebLogic JDBC client and the databases that it accesses, with the WebLogic Server in the middle. This relationship is defined by a JDBC Connection object. There are several ways to create and use JDBC Connections; a WebLogic JDBC client can create a JDBC Connection by setting up certain properties, identifying the right JDBC drivers, and making a connection. A JDBC Connection object can be cached (saved) in the T3Client's Workspace on the WebLogic Server. JDBC Connections can also be created when the WebLogic Server starts up, as a pool of connections available to one or more clients.

WebLogic JDBC, the WebLogic Server, and databases

The WebLogic Server has many features that can enhance a JDBC application, but all that is required of a WebLogic JDBC application is to connect to a WebLogic Server at the beginning of the session and disconnect at the end. The connection between the WebLogic Server and the DBMS is handled transparently.

Using third-party JDBC 2.0 drivers in a multitier configuration

You may use third-party JDBC 2.0 drivers with WebLogic JDBC and WebLogic Server. Such use requires that you run WebLogic Server or WebLogic JDBC under Java 2 (JDK 1.2.x). There are currently limitations regarding the use of Java 2 that you should consider when using JDBC 2.0 drivers. These limitations are discussed on the WebLogic platforms page. Note that objects returned by a third party JDBC driver that do not implement Serializable or Remote interfaces cannot be passed to a T3 client application. BLOB/CLOB's are not supported with WebLogic's JDBC T3 and RMI drivers.

When you use a third-party JDBC 2.0 driver in a multitier configuration, all of the driver's calls and the returned data are transparently passed through the WebLogic multitier driver. This allows you to use any functionality available in that driver in a WebLogic multitier configuration.

To use a JDBC 2.0 driver in a multitier configuration, make the following changes in your code:

  1. Change the portion of your Java code where you register the JDBC driver:

    Change this to this
    weblogic.jdbc.t3.Driver weblogic.jdbc20.t3.Driver
    weblogic.jdbc.pool.Driver weblogic.jdbc20.pool.Driver
    weblogic.jdbc.jts.Driver weblogic.jdbc20.jts.Driver

  2. Change the portion of your Java code that contains the JDBC driver URL:

    Change this to this
    jdbc:weblogic:t3 jdbc20:weblogic:t3
    jdbc:weblogic:pool jdbc20:weblogic:pool
    jdbc:weblogic:jts jdbc20:weblogic:jts

  3. If you are using the CLOB or BLOB datatypes, row caching is not supported. To turn off row caching, set the following connection property in your code:
      weblogic.t3.cacheRows=0

  4. Re-compile your code.

Top of the page

II. The WebLogic JDBC API

API Reference

Package java.sql
Package java.math
Package weblogic.jdbc.common
Class java.lang.Object
   Interface java.sql.CallableStatement
    (extends java.sql.PreparedStatement)
   Interface java.sql.Connection
   Interface java.sql.DatabaseMetaData
   Class java.util.Date
      Class java.sql.Date
      Class java.sql.Time
      Class java.sql.Timestamp
   Class java.util.Dictionary
      Class java.util.Hashtable
       (implements java.lang.Cloneable)
          Class java.util.Properties
   Interface java.sql.Driver
   Class java.sql.DriverManager
   Class java.sql.DriverPropertyInfo
   Class java.math.BigDecimal
   Class java.math.BigInteger
   Interface java.sql.PreparedStatement
    (extends java.sql.Statement)
   Interface java.sql.ResultSet
   Interface java.sql.ResultSetMetaData
   Interface java.sql.Statement
   Class java.lang.Throwable
      Class java.lang.Exception
         Class java.sql.SQLException
            Class java.sql.SQLWarning
               Class java.sql.DataTruncation
   Class java.sql.Types
   Interface weblogic.jdbc.common.JdbcServicesDef
   Interface weblogic.jdbc.common.Pool
   Class weblogic.jdbc.t3.Connection
    (implements java.sql.Connection)
   Class weblogic.jdbc.pool.Connection
    (implements java.sql.Connection)
   Class weblogic.jdbc.pool.Driver
    (implements java.sql.Driver)
   Class weblogic.jdbc.t3.Statement
    (implements java.sql.Statement)

WebLogic provides extensions to JDBC for certain WebLogic JDBC enhancements (some support jdbcKona JDBC extensions in a multitier environment). Currently there are six classes with extensions to JDBC for WebLogic JDBC:

    Class weblogic.jdbc.t3.Connection
    Class weblogic.jdbc.t3.Statement
    Class weblogic.jdbc.pool.Connection
    Class weblogic.jdbc.pool.Driver

Top of the page

WebLogic JDBC objects and their classes

WebLogic JDBC implements JDBC (current version is 1.22). The JDBC implementation is not covered in this developer guide. However, we do provide JavaSoft's classdocs (API reference materials) along with our other online reference. Anyone can freely download the JDBC classes and API documentation; go to JavaSoft. Documented here are those objects and classes specific to WebLogic JDBC's use in the WebLogic framework.

The classes that you import in WebLogic JDBC applications include:

  • java.sql.* for use with the driver weblogic.jdbc.t3.Driver
  • weblogic.common.T3Client
  • java.util.Properties

Other classes

weblogic.common.T3Client
weblogic.common.T3User
weblogic.common.T3Exception
The weblogic.common.* package contains the T3Client class, which instantiates a T3Client, the T3-specific object that WebLogic JDBC uses to function within the WebLogic framework. Also included in this package is the T3User class. A T3User object is used to pass username and password information to a secure WebLogic Server, that is, one that requires authentication for access.

weblogic.jdbc.t3.Connection
WebLogic has extended JDBC for the T3Client to be able to reset the cacheRows property on the connection. Only the extensions are covered in WebLogic's API reference and documentation; other information about JDBC is available at the sun site.

java.util.Properties
The java.util.Properties object is used as an argument to construct the JDBC Connection object.
Top of the page

Upgrading to JDK 1.1x

With WebLogic release 3.0, you should have upgraded your use of WebLogic JDBC to the latest release of the 1.1 version of the Java Developers Kit. WebLogic no longer supports JDK 1.0.2. Running the WebLogic Server against the 1.0.2 JVM is no longer supported, and running or compiling your WebLogic applications against 1.0.2 is also no longer supported.

A significant change between the 1.0.2 and 1.1 versions of the JDK is that the JDBC classes (java.sql.*) are included in the JDK 1.1. The temporary set of JDBC classes that WebLogic provided -- xjava.sql.* and weblogic.db.xjdbc.* -- are no longer necessary for use with JDK 1.1.

How to upgrade

  1. Change the import statements that reference xjava.sql.* and weblogic.db.xjdbc.* to java.sql.* and weblogic.db.jdbc.*. Here is an example:
      import java.sql.*;
      import weblogic.db.jdbc.*;

    Details. Change all references in your code from xjava.sql.* to java.sql.* when you begin using JDK 1.1. (If you are using dbKona, you will also need to change references to weblogic.db.xjdbc.* to weblogic.db.jdbc.*. This may mean just changing the import statements. You should also check your code for explicit references to xjava.sql.* and weblogic.db.xjdbc.* classes.

    There are implementation examples in the next section.

  2. Change the references to the WebLogic JDBC driver class name to weblogic.jdbc.t3.Driver; change the reference to the WebLogic JDBC URL to jdbc:weblogic:t3.

    Details. One change we have made is the introduction of a new naming convention to make the change to JDK 1.1 more consistent. We have introduced a new class, weblogic.jdbc.t3.Driver, which is identical to weblogic.jdbc.t3client.Driver, but it uses java.sql.* instead of xjava.sql.*. You should change references to the WebLogic JDBC driver URL to jdbc:weblogic:t3 and to the WebLogic JDBC driver class name to weblogic.jdbc.t3.Driver.

Top of the page

III. Implementing with WebLogic JDBC

Steps to building a WebLogic JDBC application are covered here. The simple application that is used in the full code example makes a connection to an Oracle database via a WebLogic Server, inserts, updates, and deletes a series of records, and creates and uses stored procedures and functions. Other examples included in the step-by-step discussion show similar code for use with a Sybase database, particularly in the section on stored procedures and functions.

The first five steps are covered in the order in which they should appear in an application, and are numbered accordingly.

A full code example for using an Oracle database with WebLogic JDBC is reproduced at the end of this document. It incorporates many of the code examples used in the step-by-step instructions.

If you are using a WebLogic jdbcKona two-tier driver between the WebLogic Server and the DBMS, you should also check the notes for the particular two-tier jdbcKona driver you are using.

Step 1. Importing packages

Import the following into your WebLogic JDBC application:

  • java.sql.*
  • weblogic.common.*
  • java.util.Properties
You import java.util.Properties so that you can create a Properties object to set parameters for accessing the DBMS. The weblogic.common.* package contains classes that are shared by all applications that function within the WebLogic framework. For more information on these classes, see WebLogic JDBC and their classes.

Declare the Connection object at the top of your method, since it is used in the try and the finally blocks.

Also, declare the T3Client object before the try block unless you will be using an embedded T3Client. Added as a feature in release 2.3.2, an embedded T3Client is set up by adding another property to the java.util.Properties object. An embedded T3Client is constructed and connected automatically, and can be used in any WebLogic JDBC class where you do not need an explicit T3Client object for other operations. For more on using explicit or embedded T3Clients, see Creating the T3Client.

Top of this section

Step 2. Creating the T3Client

Using an explicit or an embedded T3Client

In general, each WebLogic JDBC application begins with the creation of a T3Client object. (A T3Client may be created automatically for you, if you use the embedded T3Client feature available in release 2.3.2 and after.) The T3Client becomes the client context for this client within a WebLogic Server and uniquely identifies the client and its requests. A T3Client also owns its Workspace inside the WebLogic Server which persists and allows a T3Client to reconstitute itself for successive WebLogic Server sessions. For WebLogic JDBC applications, the T3Client is also one of the properties passed to the constructor for the JDBC Connection.

The T3Client class, weblogic.common.T3Client, contains constructors and several methods that we use in WebLogic JDBC. You can create a new T3Client, or you can reconstitute a previously created Workspace and return the T3client to the state in which you left it. A client's Workspace includes access to a set of cached JDBC connections that are set aside in the WebLogic Server for a group of WebLogic JDBC Clients.

All T3Client constructors require at least one argument, which is the URL of the WebLogic Server and (optionally, if the port is not 80) the TCP port at which the WebLogic Server is listening for T3Client connection requests. The URL is expressed after the format:

  accessProtocol://WebLogicServerURL:port

The accessProtocol may be any of the protocols described in Writing a T3Client application, including t3 (standard T3Client access over a high-performance, multiplexed, asynchronous, bidirectional connection), t3s (T3Client access authenticated and/or encrypted with SSL), or http (T3Client access over HTTP tunneling, for transfirewall access).

The WebLogicServerURL is determined by whatever method is appropriate on that machine. The port is the port at which the WebLogic Server is listening for T3Client login requests.

Here is an example of constructing a T3Client:

  T3Client t3 = null;
  try {
    t3 = new T3Client("t3://bigbox:7001");

Each T3Client has a Workspace inside the WebLogic Server into which it can save its context and revisit at a later time. You can even name the T3Client's Workspace at the time you create the T3Client, which offers an easy way to revisit the Workspace; or you can get the default T3Client's Workspace after the T3Client connects. Workspaces are powerful models for creating integrated business applications; read more about Workspaces in Using the T3Client Workspace.

For WebLogic JDBC clients, a named Workspace area includes access to any cached JDBC connections to the database (the connectionID), as well as the values set for hard, soft, and idle disconnects. A T3Client can also save arbitrary objects, identified by a String key, into its Workspace for later retrieval.

One way to create a revisitable Workspace is by naming it. You name the Workspace when the T3Client is constructed by providing a String name as an argument to the constructor. For example:

  t3 = new T3Client("t3://bigbox:7001", "mike");

Another way of creating a reenterable Workspace is by saving the String ID of the T3Client's default Workspace, which can be used to reenter it. The ID of the Workspace is available after the T3Client has connected to the WebLogic Server. Here is an example:

  t3 = new T3Client("t3://bigbox:7001");
  t3.connect();
  String wsid = t3.services.workspace().getWorkspace().getID();

You can then use the Workspace ID (or a T3Client's name) to create a new T3Client, as follows:

  t3.disconnect();
  t3 = null;

  // Reconnect using the "wsid"
  System.out.println("Reconnecting client " + wsid);
  t3 = new T3Client("t3://bigbox:7001", wsid);
  t3.connect();

If you supply a string that does not match any Workspace IDs or T3Client names currently known to the WebLogic Server, it will assume that you want to create a new Workspace and will name it with the supplied string.

When you have completed work with the WebLogic Server, you should dispose of the client's resources by calling the disconnect() method in a finally block (covered in the Final Step below).

You can set several disconnect timeouts for a T3Client, after you have a T3Client object. WebLogic supports timeouts for hard disconnects (where the socket between the WebLogic Server and its client goes away) and soft disconnects (where the T3Client requests a disconnect by calling its disconnect() method). You can set timeouts for these (in minutes) to delay cleanup of the T3Client object in the WebLogic Server, as follows:

  t3.setSoftDisconnectTimeoutMins(5);
The default for both hard and soft disconnects is an immediate cleanup of the T3Client resources in the WebLogic Server. You can also set these values to T3Client.DISCONNECT_TIMEOUT_NEVER to set the timeout to unlimited.

Setting the disconnect timeout determines how long the WebLogic Server will wait after a particular type of disconnect to clean up (destroy) a T3Client's resources -- specifically, its Workspace. Setting a T3Client's soft disconnect timeout to DISCONNECT_TIMEOUT_NEVER essentially extends the lifetime of the T3Client for as long as the WebLogic Server runs.

There is a code example that includes naming a T3Client and setting its disconnect timeouts in Using a named, cached JDBC Connection.

Top of this section

Step 3. Setting properties for connecting

After you have established a WebLogic Server session, you can begin the process of connecting to the DBMS through the WebLogic Server. You will use JDBC Properties objects for setting connection parameters.

The Properties objects contain all the information necessary for making a JDBC Connection. A set of Connections can be cached inside a T3Client's Workspace for that T3Client's use, and the T3Client can request one of its cached connections when it executes the getConnection() method with a connection ID. Connection IDs are created very simply: by setting a Property. If the connection ID exists, then it is used; otherwise, a new connection ID is created, and with it is saved all of the other Property information for the JDBC Connection. When you used the cached Connection again, all you will need is the connection ID; the Properties objects are ignored if a connection ID exists.

Properties contain the details about how a WebLogic JDBC client should access both the database and the WebLogic Server. After a Properties object is constructed, you can set any number of properties with the put() method, by supplying two arguments: the name of the property and its String value. The properties that we set here in the examples are used by the WebLogic JDBC drivers. You may include any other properties that your particular JDBC driver requires.

We use two Properties objects. The first, dbprops in the example below, set parameters for the connection between the WebLogic Server and the DBMS, which you can think of as the two-tier connection.

The second Properties object, t3props in the example below, sets parameters for the connection between the WebLogic JDBC Client and the DBMS, with the WebLogic Server between them; we also refer to this as the multitier connection. The WebLogic Server-DBMS Properties object (dbprops) will itself be set as a property of the WebLogic JDBCClient-WebLogic Server-DBMS Properties object (t3props), which will then be used as an argument for the JDBC Connection constructor.

We use a java.util.Properties object to set parameters for the connection between the WebLogic Server and the DBMS (the two-tier connection) and the connection between the WebLogic JDBCClient and the DBMS, with the WebLogic Server between them (the multitier connection). The Properties object is then used as an argument for the getConnection() method.

For clarity, we have divided the list of Properties into those that apply to the two-tier connection and those that apply to the multitier connection.

Properties to be set for the two-tier connection

user
Username for accessing the DBMS.

password
Password for accessing the DBMS.

server
Name of the DBMS. The server property may also be set as part of the URL in the multitier property weblogic.t3.driverURL, added after the URL for the driver, as in "weblogic:jdbc:oracle:DEMO" for an Oracle DBMS with the V2 alias "DEMO".

db or database
Name of the database. Required by some JDBC drivers.

There are additional optional properties that you may set for the two-tier connection, including:

weblogic.oci.cacheRows
(Oracle only) Support for Oracle array fetches. With release 2.5, jdbcKona/Oracle supports Oracle array fetches. With this change, calling ResultSet.next() the first time will get an array of rows and store it in memory, rather than retrieving a single row. Each subsequent call to next() will read a row from the rows in memory until they are exhausted, and only then will next() go back to the database.

Note that there is a different property, weblogic.t3.cacheRows, which adjusts the size of the multitier cache for buffering records on the WebLogic Server. These properties are not related although they may be used together.

Properties to be set for the multitier connection

weblogic.t3 or weblogic.t3.serverURL
Set weblogic.t3 to the T3Client object. The T3Client has a unique context within the WebLogic Server that is defined and maintained by this object. If you have need for an explicit T3Client object in your program, you will set this property.

If you are using an embedded T3Client, you will not set this property, but will set instead the property weblogic.t3.serverURL, which identifies the WebLogic Server to which the embedded client will connect. For more information on using an embedded T3Client, see Setting up an embedded T3Client.

weblogic.t3.dbprops
The properties object for the two-tier connection itself becomes a property for the multitier connection.

weblogic.t3.driverClassName
Classname of the JDBC driver between the WebLogic Server and the DBMS. This may be the class name of any JDBC driver. The string set by this property is used as an argument for the Class.forName().newInstance() method on the WebLogic Server. The driver used in this example is the WebLogic jdbcKona/Sybase native JDBC driver. Note that evaluation of the class name of the driver is case-sensitive. As with all classnames, this class name is in dot-notation.

weblogic.t3.driverURL
URL of the two-tier JDBC driver between the WebLogic Server and the DBMS (and optionally, the database server name, if not set as the server property). This URL is for the driver whose class name is specified in the weblogic.t3.driverClassName property. (More info on this is available in Using URLs with WebLogic products.) The string set by this property is used as the first argument for the DriverManager.getConnection() method on the WebLogic Server. In this example, we are accessing a Sybase database "DEMO" with the WebLogic jdbcKona/Sybase native JDBC driver. If you do not supply a server name, the system will look for an environment variable (DSQUERY in the case of Sybase, and ORACLE_SID in the case of Oracle). Evaluation of the URL is not case-sensitive. The URL is delimited by colons.

URLs for the WebLogic 2-tier native drivers are:

  • jdbc:weblogic:informix4
  • jdbc:weblogic:oracle
  • jdbc:weblogic:sybase
  • jdbc:weblogic:mssqlserver
  • jdbc:weblogic.mssqlserver4

weblogic.t3.connectionID (optional)
A named, cached JDBC Connection. You can create a Hashtable of Connection objects inside the Workspace of a T3Client that are available for that T3Client's use and persist in the T3Client's Workspace as long as the T3Client is connected to the WebLogic Server. These cached connections allow the T3Client to resume a JDBC Connection over several sessions. A cached connection ID includes all of the properties initially used to establish the JDBC Connection; consequently, if a connection ID is supplied as an argument to the getConnection() method, other properties supplied with java.util.Properties objects are used only if the connection ID doesn't already exist on the WebLogic Server.

weblogic.t3.cacheRows (optional)
Number of rows to be cached. This optional property sets the number of rows cached at the client for each roundtrip between the T3Client and the database. Caching rows can improve performance on the client. This property allows you to fine-tune caching for your application.

When a client calls ResultSet.next() for the first time, WebLogic fetches a batch of rows from the DBMS and transmits them to the client JVM in a single response. Subsequent calls to ResultSet.next(), retrieve the rows cached in client memory, without calling WebLogic. When the client's cache of rows is exhausted, the next call to ResultSet.next() is passed to WebLogic, which again retrieves a batch of rows to send to the client cache.

The number of rows fetched in a batch is configurable via the property weblogic.t3.cacheRows. The default for this property was originally 10 rows; with release version 2.5, the default has been increased to 25. You can set it to a larger or smaller size by specifying this property. To turn off caching, set the property to zero. Then each next() or getXXX() method call will require a single roundtrip between the database and the T3Client.

There are some combinations of applications and DBMSs that require WebLogic to pass records straight through to the client. For example, when an application is processing a cursor, pre-fetching row data causes a skew between the client's sense of cursor position and that of the DBMS driver. For these applications, setting the weblogic.t3.cacheRows property to zero ('0') provides the needed behavior.

You can control the cacheRows property for each query by resetting this property on the Connection object before retrieving the results of a query into a ResultSet. Use the WebLogic extensions to JDBC found in weblogic.jdbc.t3.Connection.cacheRows() to get the current value and set a new value. Results will continue to be cached according to the current cacheRow setting until it is reset.

Note that if you are using jdbcKona/Oracle, you also have access to Oracle's array fetch functionality through the two-tier property weblogic.oci.cacheRows. (Read more about this feature in the Developers Guide for jdbcKona/Oracle.) This property is independent of weblogic.t3.cacheRows, but both may be used together to offset the effects of latency and database load on performance.

weblogic.t3.blobChunkSize (optional, for use with jdbcKona/Oracle)
Defines the buffer size used for streaming blobs between WebLogic and the WebLogic client. This property is used in conjunction with the two-tier Oracle driver properties

weblogic.t3.name (optional)
The name property allows you to set the name of the connection, which will appear in the Console as the name in the connection's ManagedObject display.

weblogic.t3.description (optional)
The description property allows you to set a short description of the connection, which will appear in the Console as the description in the connection's ManagedObject display.

For example, for a connection that is being used to access customer information, you might add these two properties, as shown here:

  Properties t3props = new Properties();
  t3props.put("weblogic.t3.name",     "CustInfo");
  t3props.put("weblogic.t3.description",
              "customer info connection");

Setting this information will make the display in the WebLogic Console both more informative and easier to use.

There is one additional property listed here for reference. It is not likely to be used with most of the other properties here, since this property accesses a JDBC Connection from a connection pool. When you set this property, you do not need to set any other properties, since the other attributes for the connection are set when the connection pool is created. This property is usually used in the absence of other properties. It is:

weblogic.t3.connectionPoolID (used with the weblogic.t3 property only)
Identifies a pool of JDBC Connections that is created for access by certain T3Users. Check Using connection pools for more information and a code example. Using a connection from a pool requires that the connection pool was created (by an entry in the weblogic.properties file) when the WebLogic Server was started.

It is important to understand that you will set parameters for two connections:

  • a two-tier connection between the WebLogic Server and the DBMS
  • a multitier connection between the WebLogic JDBC client, the WebLogic Server, and the DBMS

In this example, we first set two-tier connection properties to connect to a Sybase database ("mydb") on the database server ("DEMO") with the WebLogic native JDBC driver for Sybase, jdbcKona/Sybase.

    Properties dbprops = new Properties();
    dbprops.put("user",                    "sa");
    dbprops.put("password",                "");
    dbprops.put("server",                  "DEMO");
    dbprops.put("database",                "mydb");
Then we set the multitier properties. Note that one of the multitier properties is the two-tier Properties object. Also note that we supply a connection ID as part of the multitier properties; if this connection ID identifies a Connection (and its set of Properties) that already exists, then the other properties are ignored, since they have been saved with the connection ID.
    Properties t3props = new Properties();
    t3props.put("weblogic.t3", t3);
    t3props.put("weblogic.t3.dbprops", dbprops);
    t3props.put("weblogic.t3.driverClassName",
                "weblogic.jdbc.dblib.Driver");
    t3props.put("weblogic.t3.driverURL",  
                "jdbc:weblogic:sybase");
    t3props.put("weblogic.t3.connectionID",
                dbconnid);
    t3props.put("weblogic.t3.cacheRows", "100");
    t3props.put("weblogic.t3.name", "CustInfo");
    t3props.put("weblogic.t3.description",
                "customer info connection");
Note that the formats of the class name of the driver and the URL are different; the class name uses dot-notation, and the URL uses separating colons.

Using a URL to set WebLogic JDBC properties

Some development environments set restrictions on the use of a java.util.Properties object for setting multiple database properties. For example, Powersoft's PowerJ uses the Properties object exclusively for setting the username and password for the DBMS. WebLogic has developed a URL scheme to supply all of the other information needed for a WebLogic JDBC connection. For more information on setting WebLogic JDBC properties for connection with a URL, read the Developers Guide, Using URLs with WebLogic products.

Setting up an embedded T3Client

If you do not need an explicit T3Client object for other purposes in your WebLogic JDBC program, you can use an embedded T3Client. An embedded T3Client is created, connected, and disconnected automatically for you underneath. All you must do is set another property in your java.util.Properties object that supplies the URL of the WebLogic Server.

Here is a simple example of using an embedded T3Client; this example uses the weblogic.jdbc.t3.Driver for use with JDK 1.1, which contains all of the java.sql JDBC classes. Note that there is no declaration nor construction of a T3Client object in this example.


  Class.forName("weblogic.jdbc.t3.Driver").newInstance();
  // Set up properties for connecting to the DBMS
  Properties dbprops = new Properties();
  dbprops.put("user",                  "scott");
  dbprops.put("password",              "tiger");
  dbprops.put("server",                "DEMO20");

  Properties t3props = new Properties();
  t3props.put("weblogic.t3.dbprops",         dbprops);
  // Set the URL of WebLogic to create an embedded T3Client
  t3props.put("weblogic.t3.serverURL",      "t3://localhost:7001");
  t3props.put("weblogic.t3.driverClassName",
              "weblogic.jdbc.oci.Driver");
  t3props.put("weblogic.t3.driverURL",      "jdbc:weblogic:oracle");
  t3props.put("weblogic.t3.cacheRows",      "10");

  Connection conn =
    DriverManager.getConnection("jdbc:weblogic:t3", t3props);
  Statement stmt = conn.createStatement();
  stmt.execute("select * from empdemo");
  ResultSet rs = stmt.getResultSet();

  while (rs.next()) {
    System.out.println(rs.getString("empid") + " - " + 
                       rs.getString("name")  + " - " + 
                       rs.getString("dept"));
  }

  ResultSetMetaData rsmd = rs.getMetaData();

  stmt.close();
  conn.close();
}
You can also set up an embedded T3Client to use a JDBC Connection from a WebLogic JDBC connection pool, by setting the property weblogic.t3.connectionPoolID. If you are using a JDBC Connection from a connection pool, you will need only the properties that are required for requesting a connection from the pool, as well as the property weblogic.t3.serverURL property. For more information on pools, read Using connection pools.

You can also use an embedded T3Client even if you need to set a username and password for a T3User for T3Client-to-WebLogic security. Here is an example. This sets up access to a connection pool "eng" for which the T3User "development" has been added to the weblogic.properties file, as well as a Permission to "reserve" a connection from this pool, with these properties:

  weblogic.password.development=3Y(sf40!VmoN
  weblogic.allow.reserve.weblogic.jdbc.connectionPool.eng=development

Here is how you would use a connection from this connection pool with an embedded T3Client:

  Properties t3props = new Properties();
  t3props.put("weblogic.t3.serverURL",        "t3://localhost:7001");
  t3props.put("weblogic.t3.connectionPoolID", "eng");
  t3props.put("weblogic.t3.user",             "development");
  t3props.put("weblogic.t3.password",         "3Y(sf40!VmoN");

Note that all of the other properties for connecting, like the location of the database server, are set by the configuration entry in the weblogic.properties file that creates the connection pool at startup. You can find an example entry for a connection pool (commented-out) in the properties file that is shipped with the distribution.

Top of this section

Step 4. Connecting to the DBMS

The WebLogic JDBC client never connects directly to the database, but connects to the WebLogic Server, which accesses the database on behalf of the T3Client. You must supply JDBC drivers for both the two-tier connection (between the WebLogic Server and the DBMS) and the multitier connection (between the WebLogic JDBC client, the WebLogic Server, and the DBMS). The class name and the URL of the two-tier connection is set with a Properties object, as described above.

For the connection between the WebLogic JDBC client, the WebLogic Server, and the DBMS, you will supply the class name and URL for the WebLogic JDBC driver, which manages the multitier connection.

The WebLogic JDBC driver class name is supplied by calling the Class.forName().newInstance() method with the class name weblogic.jdbc.t3.Driver. Calling Class.forName().newInstance() properly loads and registers the driver class.

You supply the URL jdbc:weblogic:t3 for this driver as an argument to the DriverManager.getConnection() method.

In this example, we use the Class.forName().newInstance() method to identify and load the WebLogic JDBC driver. Then we create the JDBC Connection with the URL of the WebLogic JDBC driver and a Properties object:

    // Class name for the WebLogic JDBC
    Class.forName("weblogic.jdbc.t3.Driver").newInstance();
    Connection conn =
      DriverManager.getConnection("jdbc:weblogic:t3",
                                  t3props);

Once you have established a Connection (that is, constructed a JDBC Connection object), you use WebLogic JDBC methods just as you would any other implementation of JDBC.

Top of this section

Cached connections and connection pools

WebLogic provides ways to supply your T3Clients with reusable JDBC Connections. Logging into a DBMS can be an expensive and time-consuming operation. With a reusable connection, the overhead of connecting to the DBMS is incurred just once, when the connection is created. The WebLogic Server holds the connection open until it is needed again.

One type of reusable connection is a named, cached JDBC Connection. Another type is a connection pool.

A cached JDBC Connection is created, probably used, and then saved in the T3Client's Workspace for later use. Caching a JDBC Connection saves overhead in having to create a Connection over and over again, but a cached Connection also ties up database resources on a long-term basis. When you cache a JDBC Connection, you save its entire state with it.

A pool of JDBC Connections can be created when the WebLogic Server starts up, before there are any requests for JDBC Connections, or dynamically by a T3Client. You can also create a connection pool dynamically using the weblogic.Admin class create_pool command.

As T3Clients connect to the WebLogic Server, they can obtain a connection from the pool, and then return it to the pool when finished. Creating a pool of connections is a good way to allocate scarce resources (like database connections) among multiple clients. You can set the pool to grow incrementally when all of the connections have been allocated, up to a maximum number of connections. You can also assign sets of users to named pools. A connection pool saves WebLogic Server and DBMS overhead in creating connections, since the connections are created once, and then reused over and over again.

Connection pools and cached connections are different. A cached JDBC Connection is created by a particular T3Client, and the details about that JDBC Connection are stored in that T3Client's Workspace. The cached connection lasts only the lifetime of the T3Client. As soon as the WebLogic Server cleans up the resources for that T3Client, the cached connection is destroyed.

Connection pools, on the other hand, are available to any T3Client. The lifetime of a connection from a connection pool is not tied in any way to the lifetime of a T3Client. When a T3Client closes a connection from a connection pool, the connection is returned to the pool and becomes available again for other T3Clients, but the connection itself is not closed.

Following are more details on how to create and use cached JDBC Connections and connection pools. These are specifically "client-side" Connections and connection pools. You can also take advantage of another WebLogic enhancement to JDBC for server-side connection pools, for use in HTTP servlets and other applications that do not use a T3Client. For more information on using server-side connection pools, read the pertinent section in the Developers Guide, Using WebLogic HTTP servlets.

Top of this section

Using a named, cached JDBC Connection

You can create and name a JDBC Connection and cache the Connection on the WebLogic Server in the T3Client's Workspace so that you can reuse the same JDBC Connection again and again. A T3Client's cached JDBC Connection will last the lifetime of the T3Client's persistence on the WebLogic Server. You can make this lifetime indefinite -- thus giving the T3Client a permanent preserved Workspace on the WebLogic Server that will last the lifetime of the WebLogic Server -- by setting the T3Client's soft disconnect timeout to DISCONNECT_TIMEOUT_NEVER. Once you have set the soft disconnect timeout to never, disconnecting the T3Client by calling the T3Client.disconnect() method will not cause the WebLogic Server to reclaim the T3Client's resources.

In this class, we create a named JDBC Connection that we reuse several times. We identify the named JDBC Connection with the java.util.Property connectionID.

This class has two methods, a static getConnection() method to create and then reuse the JDBC Connection, and a main(). First, let's examine the code for the getConnection() method in this class.

This method returns a JDBC Connection object; if we supply a property "connectionID" that already exists on the WebLogic Server, all of the other properties for login access, etc., are ignored, and the cached JDBC Connection, which contains all the information necessary to resume connection to the database, is used instead.

  static Connection getConnection(T3Client t3, String dbconnid) 
    throws Exception  
  {

    // If a connectionID is given, the other properties are used
    // only if the connectionID doesn't exist on the WebLogic Server.
    // Other values are ignored if the connectionID exists.
    Properties dbprops = new Properties();

    // Set the two-tier props
    dbprops.put("user",                       "scott");
    dbprops.put("password",                   "tiger");
    dbprops.put("server",                     "DEMO");

    Properties t3props = new Properties();
    // Set the multitier props, including the connectionID
    t3props.put("weblogic.t3",                t3);
    t3props.put("weblogic.t3.dbprops",        dbprops);
    t3props.put("weblogic.t3.driverClassName",
                "weblogic.jdbc.oci.Driver");
    t3props.put("weblogic.t3.driverURL",
                "jdbc:weblogic:oracle");
    // If dbconnid has been cached, all the preceding properties
    // are ignored. The connection is instant
    t3props.put("weblogic.t3.connectionID",   dbconnid);

    Class.forName("weblogic.jdbc.t3.Driver").newInstance();
    return  DriverManager.getConnection("jdbc:weblogic:t3",
                                        t3props);
  }

In the next code example, we carry out the following steps:

  1. Create a T3Client.
  2. Connect to the WebLogic Server.
  3. Set the soft disconnect timeout for this client to be indefinite.
  4. Save the ID of the Workspace so that the T3Client can come back to this Workspace at a later time. You can also supply a name (like "mike") for a client as an argument when you new the T3Client object.
  T3Client t3 = new T3Client("t3://localhost:7001");
  t3.connect();
  t3.setSoftDisconnectTimeoutMins(T3Client.DISCONNECT_TIMEOUT_NEVER);
  String wsid = t3.services.workspace().getWorkspace().getID();
Then we create a named JDBC Connection to an Oracle database by calling the getConnection() method with the name "myconn."
  System.out.println("Logging into database and " +
                     "saving session as myconn");
  Connection conn = getConnection(t3, "myconn");

Now we can disconnect the T3Client and set it to null. Since the soft disconnect timeout is never, the WebLogic Server will preserve this client's resources, including its Workspace and its named JDBC Connections.

  t3.disconnect();
  t3 = null;
Next we reconnect to the WebLogic Server by creating a new T3Client named with the Workspace ID of the first client. This relinks the T3Client to the Workspace that we created with the first client; in that Workspace is stored the JDBC Connection that we cached under the name "myconn."

Then we resume the connection to the Oracle database by calling the getConnection() method with the name "myconn." All of the parameters for connecting already exist. We do some arbitrary database work and then close the JDBC Connection object.

  t3 = new T3Client("t3://localhost:7001", wsid);
  t3.connect();

  for (int j = 0; j < 5; j++) {
    System.out.println("Reestablishing database connection");
    conn = getConnection(t3, "myconn");

    System.out.println("Performing query");
    QueryDataSet qds = new QueryDataSet(conn, "select * from emp");
    qds.fetchRecords();
    System.out.println("Record count = " + qds.size());
    qds.close();
  }
  conn.close();
Once you have finished with a T3Client's resources, you can instruct the WebLogic Server to reclaim those resources by setting the T3Client's soft disconnect timeout to zero, which effects a cleanup as soon as the T3Client calls the disconnect() method, as shown here:
  t3.setSoftDisconnectTimeoutMins(0);
    t3.disconnect();
You can see the full example in examples/jdbc/t3client/connectioncache.java.

Top of this section

Using connection pools

Another method of connecting is by creating a pool of JDBC Connections from which a T3User can request a connection. You can define a connection pool in the weblogic.properties file, called a "startup" connection pool, or you can create a "dynamic" connection pool in a running WebLogic Server from within a T3Client application.

Creating a pool of JDBC Connections gives T3Clients ready access to connections that are already open. It removes the overhead of opening a new connection for each DBMS user, since the connections in the pool are shared among the members of the group.

Creating a startup connection pool

A startup connection pool is declared in the weblogic.properties file. The WebLogic Server opens JDBC connections to the database during the WebLogic startup process and adds the connections to the pool.

You define a startup connection pool with an entry after the following pattern in your weblogic.properties file. An example is commented out in the properties file that is shipped with the distribution, under the heading "JDBC Connection Pool Management:"

weblogic.jdbc.connectionPool.VirtualName=\
         url=JDBC driver URL,\
         driver=full package name for JDBC driver,\
         loginDelaySecs=seconds between each login attempt,\
         initialCapacity=initial number of connections in the pool,\
         maxCapacity=max number of connections in the pool,\
         capacityIncrement=number of connections to add at a time,\
         allowShrinking=true to allow shrinking,\
         shrinkPeriodMins=interval before shrinking,\
         testTable=name of table for connection test,\
         refreshTestMinutes=interval for connection test,\
         testConnsOnReserve=true to test connection at reserve,\
	 testConnsOnRelease=true to test connection at release,\
         props=DBMS connection properties

weblogic.allow.reserve.weblogic.jdbc.connectionPool.name=\
         T3Users who can use this pool
weblogic.allow.reset.weblogic.jdbc.connectionPool.name=\
         T3Users who can reset this pool
weblogic.allow.shrink.weblogic.jdbc.connectionPool.name=\
         T3Users who can shrink this pool

The information that you supply is shown above in red. Required information is noted. If you do not supply a value that is required, an exception is thrown when you start the WebLogic Server.

Here is a short description of the arguments for this property:

name
(Required) Name of the connection pool. You will use the name to access a JDBC Connection from this pool when you write your T3Client class.

url
(Required) URL of the JDBC 2-tier driver for the connection between the WebLogic Server and the DBMS. You can use one of the WebLogic jdbcKona drivers or another JDBC driver that you have tested in a 2-tier environment. Check the documentation for the JDBC driver you choose to find the URL.

driver
(Required) Full pathname of the JDBC 2-tier driver class for the connection between the WebLogic Server and the DBMS. Check the documentation for the JDBC driver to find the full pathname.

loginDelaySecs
(Optional) Number of seconds to wait between each attempt to open a connection to the database. Some database servers can't handle multiple requests for connections in rapid succession. This property allows you to build in a small delay to let the database server catch up.

initialCapacity
(Optional) The initial size of the pool. If this value is unset, the default is the value you set for capacityIncrement.

maxCapacity
(Required) The maximum size of the pool.

capacityIncrement
(Required) The size by which the pool's capacity is enlarged. initialCapacity and capacityIncrement work somewhat like a Java Vector, which has an initial allocation (its "capacity") and is increased in increments as necessary (capacityIncrement), up to the pool maxCapacity.

allowShrinking
(Optional. Introduced in 3.1) Whether this connection pool should be allowed to shrink back to its initial capacity, after expanding to meet increased demand. Set shrinkPeriodMins if this property is set to true, or it will default to 15 minutes. Note that allowShrinking is set by default to false, for backwards compatibility.

shrinkPeriodMins
(Optional. Introduced in 3.1) The number of minutes to wait before shrinking a connection pool that has incrementally increased to meet demand. You must set allowShrinking to true to use this property. The default shrink period is 15 minutes and the minimum is 1 minute.

testTable
(Required only if you set refreshTestMinutes, testConnsOnReserve, or testConnsOnRelease. Introduced in 4.0) The name of a table in the database that is used to test the viability of connections in the connection pool. The query select count(*) from testTable is used to test a connection. The testTable must exist and be accessible to the database user for the connection. Most database servers optimize this SQL to avoid a table scan, but it is still a good idea to set testTable to the name of a table that is known to have few rows, or even no rows.

refreshTestMinutes
(Optional, introduced in 4.0) This property, together with the testTable property, enables autorefresh of connections in the pools. At a specified interval, each unused connection in the connection pool is tested by executing a simple SQL query on the connection. If the test fails, the connection's resources are dropped and a new connection is created to replace the failed connection.

To enable autorefresh, set refreshTestMinutes to the number of minutes between connection test cycles -- a value greater than or equal to 1. If you set an invalid refreshTestMinutes value, the value defaults to 5 minutes. Set testTable to the name of an existing database table to use for the test. Both properties must be set to enable the autorefresh feature.

testConnsOnReserve
(Optional, introduced in 4.0.1) When set to true, the WebLogic Server tests a connection after removing it from the pool and before giving it to the client. The test adds a small delay in serving the client's request for a connection from the pool, but ensures that the client receives a working connection. The testTable parameter must be set to use this feature.

testConnsOnRelease
(Optional, introduced in 4.0.1) When set to true, the WebLogic Server tests a connection before returning it to the connection pool. If all connections in the pool are already in use and a client is waiting for a connection, the client's wait will be slightly longer while the connection is tested. The testTable parameter must be set to use this feature.

props
(Required) The properties for connecting to the database, such as username, password, and server. The properties are defined by, and processed by, the 2-tier JDBC driver that you use. Check the documentation for the JDBC driver to find the properties required to connect to your DBMS.

allow
This attribute was deprecated in 3.0. Set up access to a connection pool using "reserve" and "reset" Permissions as shown above.

This example, taken from the weblogic.properties file that is shipped with the WebLogic distribution, creates a connection pool named "eng," which is accessible to 3 T3Users (Guest, Joe, and Jill). It allocates a minimum of 4 and a maximum of 10 JDBC connections for an Oracle database with a username of "SCOTT," password "tiger," and server name "DEMO." The WebLogic Server sleeps for 1 second between each connection attempt to prevent refused logins from a DBMS that may be under load or on a saturated network. The connection pool shrinks back to 4 connections when connections in the pool are unused for 15 minutes or more. Every 10 minutes, unused connections are tested and refreshed if they have have gone stale.

weblogic.jdbc.connectionPool.eng=\
       url=jdbc:weblogic:oracle,\
       driver=weblogic.jdbc.oci.Driver,\
       loginDelaySecs=1,\
       initialCapacity=4,\
       maxCapacity=10,\
       capacityIncrement=2,\
       allowShrinking=true,\
       shrinkPeriodMins=15,\
       refreshTestMinutes=10,\
       testTable=dual,\
       props=user=SCOTT;password=tiger;server=DEMO

weblogic.allow.reserve.weblogic.jdbc.connectionPool.eng=\
       guest,joe,jill
weblogic.allow.reset.weblogic.jdbc.connectionPool.eng=\
       joe,jill
weblogic.allow.shrink.weblogic.jdbc.connectionPool.eng=\
       joe,jill

Note that if you have a username with a null password, you shouldn't enter an empty string for the password in the connection pool registration; rather you should simply leave it blank. Here is an example taken from the WebLogic Administrators Guide document on properties:

weblogic.jdbc.connectionPool.eng=\
       url=jdbc:weblogic:sybase,\
       driver=weblogic.jdbc.dblib.Driver,\
       loginDelaySecs=1,\
       initialCapacity=4,\
       capacityIncrement=2,\
       maxCapacity=10,\
       props=user=sa;password=;server=demo
weblogic.allow.reserve.weblogic.jdbc.connectionPool.eng=guest,joe,jill

Creating a dynamic connection pool

A JNDI-based API introduced in WebLogic release 4.0 allows you to create a connection pool from within a T3Client application. With this API, you can create a connection pool in a WebLogic Server that is already running.

Dynamic pools can be temporarily disabled, which suspends communication with the database server through any connection in the pool. When a disabled pool is enabled, the state of each connection is the same as when the pool was disabled; clients can continue their database operations right where they left off.

A property in the weblogic.properties file, weblogic.allow.admin.weblogic.jdbc.connectionPoolcreate, determines who can create dynamic connection pools. If the property is not set, then only the "system" user can create a dynamic connection pool.

For example, the following property allows users "joe" and "jane" to create dynamic connection pools:

weblogic.allow.admin.weblogic.jdbc.connectionPoolcreate=joe,jane

You can also create ACLs for dynamic connection pools by adding weblogic.allow.reserve.ACLname and weblogic.allow.admin.ACLname entries to the weblogic.properties file. For example, the following two properties define an ACL named "dynapool" that allows anyone (the "everyone" group) to use a connection pool, and users "joe" and "jane" to administer a connection pool:

weblogic.allow.admin.dynapool=joe,jane
weblogic.allow.reserve.dynapool=everyone

You associate an ACL with a dynamic connection pool when you create the connection pool. The ACL and connection pool are not required to have the same name, and more than one connection pool can make use of a single ACL. If you do not specify an ACL, the "system" user is the default administrative user for the pool and any user can use a connection from the pool.

To create a dynamic connection pool in a T3 application, you get an initial JNDI context to the WebLogic JNDI provider, and then look up "weblogic.jdbc.common.JdbcServices." This example shows how this is done:

  Hashtable env = new Hashtable();

  env.put(java.naming.factory.initial, 
                  "weblogic.jndi.WLInitialContextFactory");
  // URL for the WebLogic Server
  env.put(java.naming.provider.url, "t3://localhost:7001"); 
  env.put(java.naming.security.credentials, 
           new T3User("joe", "joez_secret_wrdz"));

  Context ctx = new InitialContext(env);

  // Look up weblogic.jdbc.JdbcServices
  weblogic.jdbc.common.JdbcServices jdbc = 
      (weblogic.jdbc.common.JdbcServices) 
      ctx.lookup("weblogic.jdbc.JdbcServices");

Once you have loaded weblogic.jdbc.JdbcServices, you pass the weblogic.jdbc.common.JdbcServices.createPool() method a Properties object that describes the pool. The Properties object contains the same properties you use to create a connection pool in the weblogic.properties file, except that the "aclName" property is specific to dynamic connection pools.

The following example creates a connection pool named "eng2" for the DEMO Oracle database. The connections log into the database as user "SCOTT" with password "tiger." When the pool is created, one database connection is opened. A maximum of ten connections can be created on this pool. The "aclName" property specifies that the connection pool will use the "dynapool" ACL in the weblogic.properties file.

 weblogic.jdbc.common.Pool pool = null;

  try {
    // Set properties for the Connection Pool.  
    // The properties are the same as those used to define a startup 
    // connection pool in the weblogic.properties file.
    Properties poolProps = new Properties();

    poolProps.put("poolName",        "eng2");
    poolProps.put("url",             "jdbc:weblogic:oracle");
    poolProps.put("driver",          "weblogic.jdbc.oci.Driver");
    poolProps.put("initialCapacity", "1");
    poolProps.put("maxCapacity",     "10");
    poolProps.put("props",           "user=SCOTT;
                                      password=tiger;server=DEMO");
    poolProps.put("aclName",         "dynapool");  // the ACL to use

    // Creation fails if there is an existing pool with the same name.
    jdbc.createPool(poolProps);
  } 
  catch (Exception e) { 
     system.out.Println("Error creating connection pool eng2.");
  }
  finally { // close the JNDI context 
         ctx.close(); 
  }

Obtaining a connection from a connection pool

Using a connection from a connection pool is nearly the same as opening a JDBC connection. The JDBC driver class is weblogic.jdbc.t3Client.Driver and the connection URL is "jdbc:weblogic:t3". To identify the connection pool you want to use, you create a java.util.Properties object and set a property called weblogic.t3.connectionPoolID to the name of the connection pool.

Using a connection from a connection pool. You use a connection from a connection pool in your client application by creating a java.util.Properties object, and setting a property called weblogic.t3.connectionPoolID to the name of the connection pool you created in the WebLogic Server's weblogic.properties file.

In this simple example, we create a T3Client, set up a Properties object, and then open a connection from the connection pool "eng," for which the weblogic.properties file entry is shown above.

  T3Client t3 = new T3Client("t3://bigbox:7001");
    t3.connect();

    // Note that we only need to set two properties,
    // the T3Client and the connectionPoolID
    Properties t3props = new Properties();
    t3props.put("weblogic.t3", t3);
    t3props.put("weblogic.t3.connectionPoolID", "eng");

    Class.forName("weblogic.jdbc.t3.Driver").newInstance();
    Connection conn =
      DriverManager.getConnection("jdbc:weblogic:t3",
                                  t3props);
    // Do any arbitrary database work
    QueryDataSet qds = new QueryDataSet(conn, "select * from emp");
    qds.fetchRecords();
    System.out.println("Record count = " + qds.size());
    qds.close();
    // Release the connection
    conn.close();
    // Disconnect the client
    t3.disconnect(); 
  }
Note that the JDBC Connection is released by this client and returned to the pool before the client disconnects. At the time when the JDBC connection is returned to the connection pool, any outstanding JDBC transactions are rolled back and closed.

Examine this code example more fully in examples/jdbc/t3client/connectionpool.java.

Waiting on a pool connection to become available. If all of the connections in a pool are in use, the client will, by default, wait until a connection becomes available. You can change this behavior for a client in two ways:

  • Disable the wait. If no connection is available, DriverManager.getConnection() gets an immediate exception.

  • Specify the number of seconds to wait for a connection. If no connection is available within the number of seconds you specify, DriverManager.getConnection() gets an exception.

To disable the wait, set the weblogic.t3.waitForConnection property to "false" in the Properties object you pass to DriverManager.getConnection():

  Properties t3props = new Properties();
  t3props.put("weblogic.t3", t3);
  t3props.put("weblogic.t3.connectionPoolID", "eng");
  t3props.put("weblogic.t3.waitForConnection", "false");

  Class.forName("weblogic.jdbc.t3.Driver").newInstance();
  Connection conn =
     DriverManager.getConnection("jdbc:weblogic:t3",
                                 t3props);

With the wait disabled, the DriverManager.getConnection() call throws an exception immediately if no connection is available.

To specify a period of time to wait for a connection to become available, set the weblogic.t3.waitSecondsForConnection property to the number of seconds you want to wait. This example waits for up to 15 seconds:

  Properties t3props = new Properties();
  t3props.put("weblogic.t3", t3);
  t3props.put("weblogic.t3.connectionPoolID", "eng");
  t3props.put("weblogic.t3.waitSecondsForConnection", "15");

  Class.forName("weblogic.jdbc.t3.Driver").newInstance();
  Connection conn =
     DriverManager.getConnection("jdbc:weblogic:t3",
                                 t3props);

Using Connection Pools with Server-side Applications

For database access from server-side applications, such as HTTP servlets, use the WebLogic Pool or JTS driver. The JTS driver provides transactional support for database operations. For database access using Enterprise JavaBeans (EJB) running in WebLogic Server, use the WebLogic JTS driver. You can also access connection pools using the Java Naming and Directory Interface (JNDI) and a DataSource object. For more information, see the following documents:

Managing connection pools

The weblogic.jdbc.common.Pool and weblogic.jdbc.common.JdbcServices interfaces provide methods to manage connection pools and obtain information about them. Methods are provided for:

Retrieving information about a pool

weblogic.jdbc.common.JdbcServices.poolExists
weblogic.jdbc.common.Pool.getProperties

The poolExists() method tests whether a connection pool with a specified name exists in the WebLogic Server. You can use this method to determine whether a dynamic connection pool has already been created or to ensure that you select a unique name for a dynamic connection pool you want to create.

The getProperties() method retrieves the properties for a connection pool.

Disabling a connection pool

weblogic.jdbc.common.Pool.disableDroppingUsers
weblogic.jdbc.common.Pool.disableFreezingUsers
weblogic.jdbc.common.pool.enable

You can temporarily disable a connection pool, preventing any clients from obtaining a connection from the pool. Only the "system" user or users granted "admin" permission by an ACL associated with a connection pool can disable or enable the pool.

After you call disableFreezingUsers(), clients that currently have a connection from the pool are suspended. Attempts to communicate with the database server throw an exception. Clients can, however, close their connections while the connection pool is disabled; the connections are then returned to the pool and cannot be reserved by another client until the pool is enabled.

Use disableDroppingUsers() to not only disable the connection pool, but to destroy the client's JDBC connection to the pool. Any transaction on the connection is rolled back and the connection is returned to the connection pool. The client's JDBC connection context is no longer valid.

When a pool is enabled after it has been disabled with disableFreezingUsers(), the JDBC connection states for each in-use connection are exactly as they were when the connection pool was disabled; clients can continue JDBC operations exactly where they left off.

You can also use the disable_pool and enable_pool commands of the weblogic.Admin class to disable and enable a pool.

Shrinking a connection pool

weblogic.jdbc.common.Pool.shrinking

A connection pool has a set of properties that define the initial and maximum number of connections in the pool (initialCapacity and maxCapacity), and the number of connections added to the pool when all connections are in use (capacityIncrement). When the pool reaches its maximum capacity, the maximum number of connections are opened, and they remain opened unless you shrink the pool.

You may want to drop some connections from the connection pool when a peak usage period has ended, freeing up resources on the WebLogic Server and DBMS.

Shutting down a connection pool

weblogic.jdbc.common.Pool.shutdownSoft
weblogic.jdbc.common.Pool.shutdownHard

These methods destroy a connection pool. Connections are closed and removed from the pool and the pool dies when it has no remaining connections. Only the "system" user or users granted "admin" permission by an ACL associated with a connection pool can destroy the pool.

The shutdownSoft() method waits for connections to be returned to the pool before closing them.

The shutdownHard() method kills all connections immediately. Clients using connections from the pool get exceptions if they attempt to use a connection after shutdownHard() is called.

You can also use the destroy_pool command of the weblogic.Admin class to destroy a pool.

Resetting a pool

weblogic.jdbc.common.Pool.reset
weblogic.jdbc.t3.Connection

You can configure a connection pool to test its connections either periodically, or every time a connection is reserved or released. Allowing the WebLogic Server to automatically maintain the integrity of pool connections should prevent most DBMS connection problems. In addition, WebLogic provides methods you can call from an application to refresh all connections in the pool or a single connection you have reserved from the pool.

The weblogic.jdbc.common.Pool.reset() method closes and reopens all allocated connections in a connection pool. This may be necessary after the DBMS has been restarted, for example. Often when one connection in a connection pool has failed, all of the connections in the pool are bad.

To refresh a single connection, use the refresh() method in the weblogic.jdbc.t3.Connection class. When you call this method, you lose any Statements and Resultsets you had on the connection, plus your application incurs the relatively high cost of opening the connection. Therefore, we recommend that you only refresh a single connection when you get an error that implies that the connection has gone bad.

You will need to explicitly cast the JDBC Connection as a (weblogic.jdbc.t3.Connection). Other than that, the refresh() method in the Connection class is used in the same way the reset() method is used for a connection pool. First try an execute action on the Connection that is guaranteed to succeed if the Connection itself is viable. Catch the exception and call the refresh() method.

Here is an example. Notice that we cast the JDBC Connection as a weblogic.jdbc.t3.Connection in the last line of this example, in order to take advantage of the WebLogic extension to JDBC.


  T3Client t3 = new T3Client("t3://localhost:7001");
  t3.connect();

  Properties t3props = new Properties();
  t3props.put("weblogic.t3",                  t3);
  t3props.put("weblogic.t3.connectionPoolID", "eng");

  Class.forName("weblogic.jdbc.t3c.Driver").newInstance();
  Connection conn =
    DriverManager.getConnection("jdbc:weblogic:t3client",
                                t3props);

  try {
    Statement stmt = conn.createStatement();

    // This SQL is guaranteed to succeed over a good connection
    // to an Oracle DBMS 
    ResultSet rs = stmt.executeQuery("select 1 from dual");

    if (rs != null) {
      while (rs.next()) {;}
    }

    rs.close();
    stmt.close();
    conn.close();
  }

  catch(SQLException e) {

    // We cast the JDBC Connection as a
    // weblogic.jdbc.t3.Connection
    // and call the refresh() method on it
    ((weblogic.jdbc.t3.Connection)conn).refresh();
  }

Top of this section

Refreshing a single pool connection

weblogic.jdbc.common.JdbcServicesDef

You can refresh a single connection from a connection pool, or reset the entire connection pool, if one or more connections in the pool go stale. For example, if the DBMS is taken down while the WebLogic Server is actively supporting a pool of connections. A connection pool autorefresh feature, introduced with WebLogic Server 4.0, can also be enabled to periodically test and refresh connections.

There are only certain instances when resetting a pool is appropriate. You should never use this feature as a routine part of a user program. Usually, what makes resetting a connection pool necessary is that the DBMS has gone down and the connections in the pool are no longer viable. Attempting to reset the pool before you are certain that the DBMS is up and available again will cause an Exception to be thrown. Resetting a pool should always be a special operation that is carried out by a user with administrative privileges.

There are several ways to reset connections pools:

  • You can use the weblogic.Admin command (as a user with administrative privileges) to reset a connection pool, as an administrator. Here is the pattern:
 $ java weblogic.Admin WebLogicURL RESET_POOL poolName system passwd
    You might use this method from the command line on an infrequent basis. There are more efficient programmatic ways that are also discussed here. For more on the T3Admin commands, read the WebLogic Administrators Guide, Running and maintaining the WebLogic Server.

  • You can use an WebLogic Events class, ActionRefreshPool, to periodically check the viability of your connection pool and automatically refresh it when needed. The ActionRefreshPool is part of WebLogic's public API, and we have written an example class that demonstrates how to use it, available in the distribution in examples/jdbc/t3client/refreshpool. Running this class also requires administrative privileges for the WebLogic Server. You can even register this class as a startup class. You will probably find it easiest to use this method to ensure the viability of connections in your connection pools.

  • You can use the reset() method from the JdbcServicesDef interface in your client application.

    The last case requires the most work for you, but also gives you more flexibility than the first two. We have provided some sample code here to show you how to use the reset() method.

Here is an example of resetting a pool using the reset() method.

  1. In a try block, test a connection from the connection pool with a SQL statement that is guaranteed to succeed under any circumstances so long as there is a working connection to the DBMS. An example is the SQL statement "select 1 from dual" which is guaranteed to succeed for an Oracle DBMS, or "select 1" which is guaranteed to succeed for Sybase, if the connection is viable.

  2. Catch the SQLException.

  3. Call the reset() method in the catch block.

This simple code example that tests the demo JDBC connection pool "eng," which is a pool of 5 connections to an Oracle DBMS:


  String poolID = "eng";

  T3Client t3 = new T3Client("t3://localhost:7001");
  t3.connect();

  Properties t3props = new Properties();
  t3props.put("weblogic.t3",                  t3);
  t3props.put("weblogic.t3.connectionPoolID", poolID);

  Class.forName("weblogic.jdbc.t3.Driver").newInstance();
  Connection conn =
    DriverManager.getConnection("jdbc:weblogic:t3client",
                                t3props);

  try {

    // If the connection isn't operable, you will get an SQLException if
    // you attempt to execute anything over it
    Statement stmt = conn.createStatement();

    // This SQL is guaranteed to succeed over a good connection
    // to an Oracle DBMS 
    ResultSet rs = stmt.executeQuery("select 1 from dual");

    // Do some arbitrary database work
    if (rs != null) {
      while (rs.next()) {;}
    }

    rs.close();
    stmt.close();
    
    // Release the connection and return it to the pool
    conn.close();
  }

  // If the try block fails, reset the pool. Note that a program
  // that calls this method should have administrator privileges.
  // You should not try to reset the pool until you are certain
  // that the database is available again.
  
  catch(SQLException e) {
    t3.services.jdbc().resetPool(poolID);
  }
This example is adapted from an example that is shipped with the distribution, in examples/jdbc/t3client/connectionpool.

Top of this section

Setting up ACLs for connection pools in the WebLogic Realm

weblogic.jdbc.connectionPool
weblogic.jdbc.connectionPool.poolID

WebLogic controls access to internal resources like JDBC connection pools through ACLs set up in the WebLogic Realm. Entries for ACLs in the WebLogic Realm are listed as properties in the weblogic.properties file.

You can set the Permissions "reserve," "reset," and "shrink" for JDBC connections in a connection pool by entering a property in the properties file. Setting a Permission for the ACL "weblogic.jdbc.connectionPool" limits access to all connection pools. Add Permissions for other users by adding an entry for the ACL name "weblogic.jdbc.connectionPool.poolID," which controls access to the connection pool poolID. The special user system always has Permissions "reserve," "reset," and "shrink" for every ACL, no matter what other Permissions have been set.

Example:
weblogic.allow.reserve.weblogic.jdbc.connectionPool.eng=margaret,joe,mary weblogic.allow.reset.weblogic.jdbc.connectionPool.eng=sysMonitor weblogic.allow.shrink.weblogic.jdbc.connectionPool.eng=sysMonitor

For backwards compatibility, you can also use the old-style property syntax to grant permission for "reserve" by setting a userlist for the property weblogic.jdbc.connectionPool.poolID=allow=. It is recommended that you upgrade your properties file as soon as possible to reflect the new usage, since WebLogic cannot guarantee how long it will support old-style properties.

Inserting, updating, and deleting records

You use a JDBC Statement or one of its subclasses, created in the context of the JDBC Connection, to execute queries on the database. The results of the query are contained in a JDBC ResultSet. Use the next() and getXXX() methods in the ResultSet class to access rows in the database.

In this example, we first insert ten records into the Employee table. We use a PreparedStatement with the JDBC PreparedStatement "?" syntax. We can make updates to the records using the setInt() and setString() methods from the PreparedStatement class.

    String inssql = "insert into emp (empno, empname) values (?, ?)";
    PreparedStatement pstmt = conn.prepareStatement(inssql);
    for (int j = 0; j < 10; j++) {
      pstmt.setInt(1, i);
      pstmt.setString(2, "John Smith");
      pstmt.execute();
    }
    pstmt.close();

After inserting the values, we check what we inserted by executing a query on the database and using the ResultsSet.next() method to examine the results. We close the ResultSet and Statement objects in the reverse order in which they were instantiated.

    Statement stmt = conn.createStatement();
    ResultSet rs = stmt.execute("select empno, empname from emp");

    while (rs.next())  {
      System.out.println("Value = " + rs.getString("empno"));
      System.out.println("Value = " + rs.getString("empname"));
    }
    rs.close();
    stmt.close();

Here we update the records we inserted, using another PreparedStatement.

    String updsql = "update emp set empname = ? where empno = ?";
    PreparedStatement pstmt1 = conn.prepareStatement(updsql);

    for (int j = 0; j < 10; j++) {
      pstmt1.setInt(2, j);
      pstmt1.setString(1, "Person" + j);
      pstmt1.executeUpdate();
    }
    pstmt1.close();

In this example, we delete the records that we inserted. Again, we use a PreparedStatement and the setInt() method to select records for deletion.

    String delsql = "delete from emp where empno = ?";
    PreparedStatement pstmt2 = conn.prepareStatement(delsql);

    for (int j = 0; j < 10; j++) {
      pstmt2.setInt(1, j);
      pstmt2.executeUpdate();
    }
    pstmt2.close();

Note that we close each Statement and PreparedStatement object when we are finished using it.

Top of this section

Creating and using stored procedures and functions

You can create, use, and drop stored procedures and functions with WebLogic JDBC. Use CallableStatement objects (subclass of PreparedStatement) with JDBC PreparedStatement "?" syntax to set parameters.

In this example, we drop several stored procedures and functions from a database, using a JDBC Statement that we close when we have finished:

    Statement stmt = conn.createStatement();
    try {stmt.execute("drop procedure proc_squareInt");
      }  catch (SQLException e) {;}
    try {stmt.execute("drop procedure func_squareInt");
      }  catch (SQLException e) {;}
    try {stmt.execute("drop procedure proc_getResults");
      } catch (SQLException e) {;}

    stmt.close();

Use the JDBC Statement class to create a stored procedure or function, and use the JDBC CallableStatement class to execute them. Stored procedure input parameters are mapped to JDBC IN parameters, using the CallableStatement.setXXX() methods like setInt(), and JDBC PreparedStatement "?" syntax. Stored procedure output parameters are mapped to JDBC OUT parameters, using the CallableStatement.registerOutParameter() methods and JDBC PreparedStatement "?" syntax. A parameter may be both IN and OUT, which requires both a setXXX() and a registerOutParameter() call to be done on the same parameter number. For Sybase, the JDBC keyword CALL is used instead of the SQL Server keyword EXECUTE. If you are using jdbcKona/Sybase or jdbcKona/MSSQLServer for your two-tier connection, also read Using stored procedures and OpenServer RPCs in the Developers Guide for jdbcKona/Sybase and jdbcKona/MSSQLServer for more vendor-specific details.

Here we create a Sybase stored procedure, using a JDBC Statement, to square an integer. Then we execute the stored procedure using a CallableStatement. We use the registerOutParameter() method to set an output parameter.

    Statement stmt1 = conn.createStatement();
    stmt1.execute("create procedure proc_squareInt " +
                  "(@field1 int, @field2 int output) as " +
		  "begin select @field2 = @field1 * @field1 end");
    stmt1.close();

    CallableStatement cstmt1 =
      conn.prepareCall("{call proc_squareInt(?, ?)}");

    cstmt1.registerOutParameter(2, Types.INTEGER);
    for (int i = 0; i < 10; i++) {
      cstmt1.setInt(1, i);
      cstmt1.execute();
      System.out.println(i + " " + cstmt1.getInt(2));
    }
    cstmt1.close();

This example code shows how to create a Sybase stored function that returns the square of an integer. We execute the stored function with a CallableStatement, and use registerOutParameter() to register the return value.

    Statement stmt2 = conn.createStatement();
    stmt2.execute("create procedure func_squareInt (@field2 int) as " +
                  "begin return @field1 * @field1 end");
    stmt2.close();

    CallableStatement cstmt2 =
      conn.prepareCall("{? = call func_squareInt(?)}");

    cstmt2.registerOutParameter(1, Types.INTEGER);
    for (int i = 0; i < 10; i++) {
      cstmt2.setInt(2, i);
      cstmt2.execute();
      System.out.println(i + " " + cstmt2.getInt(1));
    }
    cstmt2.close();

This example code shows how to create a Sybase stored procedure that returns the results of a SQL query. We execute the stored procedure with a CallableStatement and put the results into a ResultSet.

You must process all ResultSets returned by a stored procedure using the Statement.execute() and Statement.getResultSet() methods before OUT parameters and return status are available.

    Statement stmt3 = conn.createStatement();
    stmt3.executeUpdate("create procedure proc_getResults as " +
                        "begin select name from sysusers \n" +
		        "select gid from sysusers end");
    stmt3.close();

    CallableStatement cstmt3 =
      conn.prepareCall("{call proc_getResults()}");

    boolean hasResultSet = cstmt3.execute();
    while (hasResultSet) {
      ResultSet rs = cstmt3.getResultSet();
      while (rs.next()) 
        System.out.println("Value: " + rs.getString(1));
      rs.close();
      hasResultSet = cstmt3.getMoreResults();
    }
    cstmt3.close();

Here is example code that shows how to create and call an Oracle stored procedure with Statement and CallableStatement objects. The process is similar to the Sybase procedure.

    Statement stmt1 = conn.createStatement();
    stmt1.execute("CREATE OR REPLACE PROCEDURE " +
                  "proc_squareInt (field1 IN OUT INTEGER, " +
		  "field2 OUT INTEGER) IS " +
		  "BEGIN field2 := field1 * field1; " +
		  "field1 := field1 * field1; " +
		  "END proc_squareInt");
    stmt1.close();

    CallableStatement cstmt1 =
      conn.prepareCall("BEGIN proc_squareInt(?, ?); END;");

    cstmt1.registerOutParameter(2, Types.INTEGER);
    for (int k = 0; k < 100; k++) {
      cstmt1.setInt(1, k);
      cstmt1.execute();
      System.out.println(k + " "
                         + cstmt1.getInt(1)
			 + " " + cstmt1.getInt(2));
    }
    cstmt1.close();

Finally, here is sample code for creating and using an Oracle stored function with Statement and CallableStatement objects.

    Statement stmt2 = conn.createStatement();
    stmt2.execute("CREATE OR REPLACE FUNCTION " +
                  "func_squareInt " +
                  "(field1 IN INTEGER) RETURN INTEGER IS " +
		  "BEGIN return field1 * field1; " +
		  "END func_squareInt;");
    stmt2.close();

    // Use a stored function
    CallableStatement cstmt2 =
      conn.prepareCall("BEGIN ? := func_squareInt(?); END;");

    cstmt2.registerOutParameter(1, Types.INTEGER);
    for (int k = 0; k < 100; k++) {
      cstmt2.setInt(2, k);
      cstmt2.execute();
      System.out.println(k + " "
                         + cstmt2.getInt(1)
			 + " " + cstmt2.getInt(2));
    }
    cstmt2.close();

Top of this section

Final Step. Closing the Connection and disconnecting the T3Client

As with all other JDBC objects, you should close() the Connection, even if your login to the database fails; otherwise you risk exceeding the maximum number of logins. You should also disconnect() the WebLogic JDBCClient from the WebLogic Server.

Call the close() and disconnect() methods in a try block inside your finally block, and catch the appropriate Exceptions. Calling these methods within a finally block guarantees that they will be executed even if the code in your main try block throws an exception and does not complete. For example:

  finally {
    if (conn != null)
      try { conn.close();   } catch (SQLException sqe)  {}
    if (t3   != null)
      try { t3.disconnect();} catch (Exception e)       {}
  }

When a client disconnects with the disconnect() method, the WebLogic Server will do a dump stack with an EOF exception. You should ignore EOF exceptions that appear in your Netscape server log on disconnect().

Top of this section

Code summary

package examples.jdbc;

import java.sql.*;
import weblogic.db.jdbc.*;
import weblogic.common.*;

import java.util.Properties;

public class t3client1 {

  public static void main(String argv[]) {

    T3Client t3 = null;
    Connection conn = null;
    try {
      t3 = new T3Client("t3://bigbox:7001");
      t3.connect();

      Properties dbprops = new Properties();
      dbprops.put("user",                  "scott");
      dbprops.put("password",              "tiger");
      dbprops.put("server",                getParameter("server"));

      Properties t3props = new Properties();
      t3props.put("weblogic.t3",           t3);
      t3props.put("weblogic.t3.dbprops",   dbprops);

      // Note that the formats of the class name of the driver and the
      // URL are different; the class name uses dot-notation, and the
      // URL uses separating colons.
      t3props.put("weblogic.t3.driverClassName",
                  "weblogic.jdbc.oci.Driver");
      t3props.put("weblogic.t3.driverURL",
                  "jdbc:weblogic:oracle");
      t3props.put("weblogic.t3.cacheRows",
                  getParameter("cacheRows"));

      Class.forName("weblogic.jdbc.t3.Driver").newInstance();
      conn = DriverManager.getConnection("jdbc:weblogic:t3client",
                                         t3props);

      // Insert a series of records
      String inssql = "insert into emp (empno, empname) values (?, ?)";
      PreparedStatement pstmt = conn.prepareStatement(inssql);
      for (int j = 0; j < 10; j++)
        pstmt.setInt(1, i);
	pstmt.setString(2, "John Smith");
	pstmt.execute();
      }
      pstmt.close();

      Statement stmt = conn.createStatement();
      ResultSet rs = stmt.executeQuery("select empno, " +
                                       "empname from emp");

      while (rs.next())  {
        System.out.println("Value = " + rs.getString("empno"));
        System.out.println("Value = " + rs.getString("empname"));
      }

      rs.close();
      stmt.close();

      // Update a series of records
      String updsql = "update emp set empname = ? where empno = ?";
      PreparedStatement pstmt1 = conn.prepareStatement(updsql);

      for (j = 0; j < 10; j++) {
        pstmt1.setInt(2, j);
        pstmt1.setString(1, "Person" + j);
        pstmt1.executeUpdate();
      }
      pstmt1.close();

      // Delete a series of records
      String delsql = "delete from emp where empno = ?";
      PreparedStatement pstmt2 = conn.prepareStatement(delsql);

      for (int j = 0; j < 10; j++) {
        pstmt2.setInt(1, j);
        pstmt2.executeUpdate();
      }
      pstmt2.close();

      // Create a stored procedures
      Statement stmt1 = conn.createStatement();
      stmt1.execute("CREATE OR REPLACE PROCEDURE " +
                    "proc_squareInt (field1 IN OUT INTEGER, " +
		    "field2 OUT INTEGER) IS " +
	      	    "BEGIN field2 := field1 * field1; " +
		    "field1 := field1 * field1; " +
		    "END proc_squareInt");
      stmt1.close();

      // Use a stored procedure
      CallableStatement cstmt1 =
        conn.prepareCall("BEGIN proc_squareInt(?, ?); END;");

      cstmt1.registerOutParameter(2, Types.INTEGER);
      for (int k = 0; k < 100; k++) {
        cstmt1.setInt(1, k);
        cstmt1.execute();
        System.out.println(k + " "
	                   + cstmt1.getInt(1)
			   + " " + cstmt1.getInt(2));
      }
      cstmt1.close();

      // Create a stored function
      Statement stmt2 = conn.createStatement();
      stmt2.execute("CREATE OR REPLACE FUNCTION " +
                    "func_squareInt (field1 IN INTEGER) " +
		    "RETURN INTEGER IS " +
		    "BEGIN return field1 * field1; " +
		    "END func_squareInt;");
       stmt2.close();

      // Use a stored function
      CallableStatement cstmt2 =
        conn.prepareCall("BEGIN ? := func_squareInt(?); END;");

      cstmt2.registerOutParameter(1, Types.INTEGER);
      for (int k = 0; k < 100; k++) {
        cstmt2.setInt(2, k);
        cstmt2.execute();
        System.out.println(k + " "
	                   + cstmt2.getInt(1)
			   + " " + cstmt2.getInt(2));
      }
      cstmt2.close();
    }
    finally {
      if (conn != null)
          try {conn.close();} catch (SQLException sqe) {}
      if (t3   != null)
          try {t3.disconnect();} catch (Exception e) {}
    }
  }
}

Top of the page

Other WebLogic JDBC features

WebLogic provides several features in its jdbcKona drivers and in WebLogic JDBC to support database-specific strengths. All of the features supported in the two-tier drivers, and other features specific to multitier use, are available in the multitier environment in WebLogic JDBC.

Waiting on Oracle resources

weblogic.jdbc.t3.Connection

With release 2.5, WebLogic supports Oracle's oopt() C functionality, which allows a client to wait until resources become available. The Oracle C function sets options in cases where requested resources are not available; for example, whether to wait for locks. This functionality is described in section 4-97 of The OCI Functions for C.

The developer can set whether a client will wait for DBMS resources, or will receive an immediate exception. Here is an example, from the example examples/jdbc/oracle/waiton.java:

  t3 = new T3Client("t3://bigbox:7001");
  t3.connect();

  java.util.Properties dbprops = new java.util.Properties();
  dbprops.put("user",     "scott");
  dbprops.put("password", "tiger");
  dbprops.put("server",   "bigbox");

  Properties t3props = new Properties();
  t3props.put("weblogic.t3",                t3);
  t3props.put("weblogic.t3.dbprops",        dbprops);
  t3props.put("weblogic.t3.driverClassName",
              "weblogic.jdbc.oci.Driver");
  t3props.put("weblogic.t3.driverURL",
              "jdbc:weblogic:oracle");
  t3props.put("weblogic.t3.cacheRows",
              getParameter("cacheRows"));

  Class.forName("weblogic.jdbc.t3.Driver").newInstance(); 

  // You must cast the Connection as a weblogic.jdbc.oci.Connection
  // to take advantage of this extension.
  Connection conn =
    (weblogic.jdbc.oci.Connection)
       DriverManager.getConnection("jdbc:weblogic:t3", t3props);
  
  // After constructing the Connection object, immediately call
  // the waitOnResources method
  conn.waitOnResources(true);

Note that use of this method can cause several error return codes while waiting for internal resources that are locked for short durations.

To take advantage of this feature, you must first cast your Connection object as a weblogic.jdbc.oci.Connection, and then call the waitOnResources() method.

Extended SQL

JavaSoft's JDBC specification includes a feature called SQL Extensions, or SQL Escape Syntax. With the release of version 2.5, WebLogic JDBC and all of the two-tier drivers support Extended SQL. It is fully documented in the Overview of the jdbcKona family of JDBC drivers.

Oracle array fetches

Version 2.5 of WebLogic's two-tier jdbcKona/Oracle driver offers support for Oracle array fetches by setting the two-tier JDBC Connection property, weblogic.oci.cacheRows. If you are using jdbcKona/Oracle, this feature is also supported in WebLogic JDBC.

Take advantage of this feature in WebLogic JDBC by setting the two-tier property weblogic.oci.cacheRows.

Multibyte character set support

Version 2.5 of WebLogic's two-tier jdbcKona/Oracle driver also offers internationalization support (AL24UTFFSS/UTF-8), which is extended to WebLogic JDBC if you are using the jdbcKona/Oracle driver with the WebLogic Server. Full documentation on this feature is available in the Developers Guide for jdbcKona/Oracle.

About WebLogic JDBC and Oracle NUMBER columns

Oracle provides a column type called NUMBER, which can be optionally specified with a precision and a scale, in the forms NUMBER(P) and NUMBER(P,S). Even in the simple unqualified NUMBER form, this column can hold all number types from small integer values to very large floating point numbers, with high precision.

WebLogic's jdbcKona/Oracle reliably converts the values in a column to the Java type requested when a jdbcKona/Oracle application asks for a value from such a column. Of course, if a value of 123.456 is asked for with getInt(), the value will be rounded.

The method getObject(), however, poses some problems. jdbcKona/Oracle guarantees to return a Java object which will represent any value in a NUMBER column with no loss in precision. This means that a value of 1 can be returned in an Integer, but a value like 123434567890.123456789 can only be returned in a BigDecimal.

There is no metadata from Oracle to report the maximum precision of the values in the column, so jdbcKona/Oracle must decide what sort of object to return based on each value. This means that one ResultSet may return multiple Java types from getObject() for a given NUMBER column. A table full of integer values may all be returned as Integer from getObject(), whereas a table of floating point measurements may be returned primarily as Double, with some Integer if any value happens to be something like "123.00". Oracle does not provide any information to distinguish between a NUMBER value of "1" and a NUMBER of "1.0000000000".

There is some more reliable behavior with qualified NUMBER columns, that is, those defined with a specific precision. Oracle's metadata provides these parameters to the driver so jdbcKona/Oracle will always return a Java object appropriate for the given precision and scale, regardless of the values in the table.

Column definition Returned by getObject()
NUMBER(P <= 9) Integer
NUMBER(P <= 18) Long
NUMBER(P >= 19) BigDecimal
NUMBER(P <=16, S > 0) Double
NUMBER(P >= 17, S > 0) BigDecimal

The multitier driver add another layer of complexity to this issue. By default, WebLogic fetches a configurable number of ResultSet rows of DBMS data before the multitier JDBC application asks for it, which improves performance as perceived by the client. But because WebLogic does not know in advance what form the client will want the data, WebLogic prefetches rows generically, so that the data sent to a client application is of the same type in any one column of a ResultSet. When using prefetch, the getObject() method cannot be used for number types, because the jdbcKona/Oracle driver in use by the WebLogic Server might return different Java types in a given column. Consequently, WebLogic prefetches all greater-than-integer numerical data in String form, to guarantee that no precision will be lost.

This has no effect on data retrieval in a WebLogic JDBC client application if the data is requested with getInt(), getFloat(), getBigDecimal(), etc. because WebLogic JDBC converts the String to the correct type. But for calls to the getObject() method, WebLogic JDBC returns the String it prefetched.

If you want getObject() to behave in the same way in your your multitier client application as in a two-tier jdbcKona/Oracle application -- that is, without prefetch, and potentially with mixed data types in the same column -- turn off row caching in WebLogic by setting the Connection property weblogic.t3.cacheRows to zero (0).

Top of the page

IV. Implementing with WebLogic JDBC and the JDBC-ODBC bridge

This notated example shows how to use WebLogic JDBC to connect to any vendor's database using the JDBC-ODBC bridge as the two-tier driver.

Note: Using the JDBC-ODBC bridge to access a Microsoft Access database with Enterprise JavaBeans is not supported.

Step 1. Importing packages

The same import packages are required for using the JDBC-ODBC bridge with WebLogic JDBC as with any other WebLogic JDBC class. They are:
import java.util.*;
import java.sql.*;
import weblogic.common.*; 
Top of this section

Step 2. Creating the T3Client

The constructor for a WebLogic JDBC client takes one argument, the URL of the WebLogic Server, which includes the port on which it is listening for T3Client requests. The example places all of the initial work of the program in a try block.
  try {
    t3 = new T3Client("t3://bigbox:7001");
    t3.connect();
You should call the disconnect() method on the t3Client in your finally block, even if the connection fails.

Top of this section

Step 3. Connecting

Use a java.util.Properties object to set parameters for connecting. We use one set of Properties for the WebLogic Server-to-DBMS connection (the two-tier connection), and another set of Properties for connection between the WebLogic JDBC client, the WebLogic Server, and the DBMS (the multitier connection). The two-tier Properties object itself is set as a multitier Property, and then the multitier Properties object is used as an argument for the Connection constructor. (details on setting Properties)

    Properties dbprops = new Properties();
    dbprops.put("user",                  "scott");
    dbprops.put("password",              "tiger");

    Properties t3props = new Properties();
    t3props.put("weblogic.t3",                t3);
    t3props.put("weblogic.t3.dbprops",        dbprops);
    t3props.put("weblogic.t3.driverClassName",
                "sun.jdbc.odbc.JdbcOdbcDriver");
    t3props.put("weblogic.t3.driverURL",
                "jdbc:odbc:Oracle_on_SS2");
    t3props.put("weblogic.t3.cacheRows",      "10");

    Class.forName("weblogic.jdbc.t3.Driver").newInstance();
    conn = DriverManager.getConnection("jdbc:weblogic:t3client",
                                       t3props);

    checkForWarning(conn.getWarnings());

In the last line in this example, we check for vendor-specific warnings after the connection is established. Here is the code for the method checkForWarning. The method takes as an argument a SQLWarning object and displays information about the SQLState, the warning message, and the database vendor's error code. Note that there may be multiple warnings in a single SQLWarning object.

  private static boolean checkForWarning (SQLWarning warn)
       throws SQLException
  {
    boolean rc = false;
    if (warn != null) {
      System.out.println ("\n *** Warning ***\n");
      rc = true;
      while (warn != null) {
	System.out.println ("SQLState: " +
			    warn.getSQLState ());
	System.out.println ("Message:  " +
			    warn.getMessage ());
	System.out.println ("Vendor:   " +
			    warn.getErrorCode ());
	System.out.println ("");
	warn = warn.getNextWarning ();
      }
    }
    return rc;
  }
Top of this section

Accessing data

Use the getMetaData method (in the Connection class) to retrieve database metadata. In this example, we display a few details about the database based on the metadata retrieved.
   DatabaseMetaData dma = conn.getMetaData();

   System.out.println("Connected to " + dma.getURL());
   System.out.println("Driver       " + dma.getDriverName());
   System.out.println("Version      " + dma.getDriverVersion());
   System.out.println("");
Use a Statement object to construct and execute a simple SQL select statement, and then retrieve the data into a ResultSet. Close the Statement and ResultSet objects when you have finished using them.
   Statement stmt = conn.createStatement();
   ResultSet rs = stmt.executeQuery("SELECT * FROM emp");
   dispResultSet (rs);

   rs.close();
   stmt.close();
We display the results of the query with a private method that takes as its argument a ResultSet. The dispResultSet() method prints the column headings for the table using ResultSetMetaData and then displays the contents of the ResultSet in row major order.
  private static void dispResultSet (ResultSet rs)
       throws SQLException
  {
    int i;

    ResultSetMetaData rsmd = rs.getMetaData ();
    int numCols = rsmd.getColumnCount();

    for (i=1; i < = numCols; i++) {
      if (i > 1) System.out.print(",");
      System.out.print(rsmd.getColumnLabel(i));
    }
    System.out.println("");

    boolean more = rs.next ();
    while (more) {
      for (i=1; i<=numCols; i++) {
	if (i > 1) System.out.print(",");
	System.out.print(rs.getString(i));
      }
      System.out.println("");
      more = rs.next ();
    }
  }
Top of this section

Exception handling

This class catches SQLExceptions with one catch block and all other Exceptions with a second catch block.

The SQLException is most interesting; we display the same information about a SQL error that we when we checked for SQLWarnings after instantiating a Connection. Note that there may be several SQL errors contained in a single SQLException.

 catch (SQLException ex) {
   System.out.println ("\n*** SQLException caught ***\n");
   ex.printStackTrace();

   while (ex != null) {
      System.out.println ("SQLState: " +
		    ex.getSQLState ());
      System.out.println ("Message:  " +
		    ex.getMessage ());
      System.out.println ("Vendor:   " +
		    ex.getErrorCode ());
      ex = ex.getNextException ();
      System.out.println ("");
   }
 }
For all other exceptions, we merely print out a stack trace for debugging purposes.
 catch (java.lang.Exception ex) {
   ex.printStackTrace ();
 }
Top of this section

Final Step. Disconnecting and closing objects

Always close the Connection and disconnect the T3Client in a finally block to ensure proper cleanup.
 finally {
   if (conn != null)
     try {conn.close();}    catch (Exception e) {;}
   if (t3   != null)
     try {t3.disconnect();} catch (Exception e) {;}
 }
Top of this section

Code summary

Here is a summary of the code discussed in this example.
package examples.jdbc.odbc;

import java.util.*;
import java.sql.*;
import weblogic.common.*;

class simpleselect {

  public static void main (String args[]) {

    String url   = "jdbc:odbc:Oracle_on_SS2";
    String query = "SELECT * FROM emp"; 

    T3Client   t3   = null;
    Connection conn = null;
    try {

      t3 = new T3Client("t3://bigbox:7001");
      t3.connect();

      Properties dbprops = new Properties();
      dbprops.put("user",                  "scott");
      dbprops.put("password",              "tiger");

      Properties t3props = new Properties();
      t3props.put("weblogic.t3",                t3);
      t3props.put("weblogic.t3.dbprops",        dbprops);
      t3props.put("weblogic.t3.driverClassName",
                  "sun.jdbc.odbc.JdbcOdbcDriver");
      t3props.put("weblogic.t3.driverURL",      url);
      t3props.put("weblogic.t3.cacheRows",      "10");

      Class.forName("weblogic.jdbc.t3.Driver").newInstance();
      conn = DriverManager.getConnection("jdbc:weblogic:t3client",
                                         t3props);

      checkForWarning(conn.getWarnings());

      DatabaseMetaData dma = conn.getMetaData();

      System.out.println("Connected to " + dma.getURL());
      System.out.println("Driver       " + dma.getDriverName());
      System.out.println("Version      " + dma.getDriverVersion());
      System.out.println("");

      // Create a Statement object so we can submit
      // SQL statements to the driver
      Statement stmt = conn.createStatement();

      // Submit a query, creating a ResultSet object
      ResultSet rs = stmt.executeQuery(query);

      // Display all columns and rows from the result set
      dispResultSet (rs);

      // Close the result set and statement
      rs.close();
      stmt.close();

    }
    catch (SQLException ex) {

      // Catch SQLExceptions and display specific error information.
      System.out.println ("\n*** SQLException caught ***\n");
      ex.printStackTrace();

      while (ex != null) {
	System.out.println ("SQLState: " +  ex.getSQLState ());
	System.out.println ("Message:  " +  ex.getMessage ());
	System.out.println ("Vendor:   " +  ex.getErrorCode ());
	ex = ex.getNextException ();
	System.out.println ("");
      }
    }
    catch (java.lang.Exception ex) {
      // For any other exception, just print out the StackTrace
      ex.printStackTrace();
    }
    finally {
      if (conn != null)
        try {conn.close();}    catch (SQLException sqe) {}
      if (t3   != null)
        try {t3.disconnect();} catch (Exception e) {}
    }
  }

  private static boolean checkForWarning (SQLWarning warn)
       throws SQLException
  {
    boolean rc = false;

    // Take an SQLWarning object and display its
    // warning messages.  Note that there could be
    // multiple warnings chained together.

    if (warn != null) {
      System.out.println ("\n *** Warning ***\n");
      rc = true;
      while (warn != null) {
	System.out.println ("SQLState: " + warn.getSQLState ());
	System.out.println ("Message:  " + warn.getMessage ());
	System.out.println ("Vendor:   " + warn.getErrorCode ());
	System.out.println ("");
	warn = warn.getNextWarning ();
      }
    }
    return rc;
  }

  private static void dispResultSet (ResultSet rs)
       throws SQLException
  {
    int i;
    ResultSetMetaData rsmd = rs.getMetaData();
    int numCols = rsmd.getColumnCount();

    for (i=1; i<=numCols; i++) {
      if (i > 1) System.out.print(",");
      System.out.print(rsmd.getColumnLabel(i));
    }
    System.out.println("");

    boolean more = rs.next();
    while (more) {
      for (i=1; i<=numCols; i++) {
	if (i > 1) System.out.print(",");
	System.out.print(rs.getString(i));
      }
      System.out.println("");
      more = rs.next();
    }
  }
}

Top of the page

V. Change history

Release 4.0.2

Fixed a problem with guest permissions being checked instead of the passed-in user for connection pools.

Fixed a problem where a weblogic.jdbc.pool.ResultSet was being created for a null java.sql.ResultSet instead of a null being returned.

Release 4.0.1

Improved the server's handling of the situation when server-side code, including EJBs, that use JDBC connections from connection pools fail to close the connection. When a t3 client running in a different JVM than the server fails to close a pool connection, the server detects this and cleans up after the client, returning the connection to the pool. When the connection is a class running in the server, however, an unclosed connection cannot be detected and is never returned to the pool. This led to deadlocks for clients waiting for connections from a pool that had been drained of its connections. The best solution to this problem is to ensure that every class that uses a JDBC pool connection closes the connection when it is finished. To improve the server's behavior, deadlocked clients now receive an Exception with a message indicating no pools are available. Also, changes were added so that when an administrator disables a pool with the option to drop current users, all reserved connections are returned to the pool and clients with reserved connections get an SQLException.

Added a change so that when the server cleans up from a dead client, it closes only JDBC connections that were not obtained from a pool. Pool connections are returned to their pool.

Added two new parameters to the connection pool property, testConnsOnReserve and testConnsOnRelease. When testConnsOnReserve is set to true, WebLogic tests that a DBMS connection is viable before giving the connection to the client. When testConnsOnRelease is set to true, WebLogic tests the connection before returning it to the connection pool. If you use either of these new parameters, you must also set the testTable parameter.

Release 4.0.0

Tengah/JDBC is renamed WebLogic/JDBC. The names have changed in the documentation. There are no related API name changes.

Added a JNDI-based API to create JDBC dynamic connection pools from within an application. Dynamic connection pools differ from connection pools defined in the weblogic.properties file (called "startup" connection pools) in that they are created in a running WebLogic Server instead of at startup time. The new API includes a set of methods for managing connection pools. These methods can be used with startup or dynamic connection pools. See Using connection pools and particularly Creating a dynamic connection pool for information about this new feature.

Added connection pool autorefresh. When autorefresh is enabled for a connection pool, at a specified interval a simple query is executed on each unused connection in the connection pool. If this test fails, the connection is closed and a new connection is created and added to the pool to replace the failed connection. Enable connection pool autorefresh by defining the refreshTestMinutes and testTable properties when you define the connection pool.

Fixed problem in shrinking a connection pool on Oracle, where an Oracle database session remained after the connection was removed from the connection pool. Expanding the pool later resulted in additional database server sessions. This fix ensures that when a connection pool shrinks, the connection environment is destroyed and the corresponding database session is ended.

Release 3.1.7

When using the jdbcKona/Oracle driver with WebLogic JDBC in a multitier configuration, Exceptions were thrown when retrieving numeric values from a localized database that uses a grouping and decimal separator characters other than the comma and period. The WebLogic JDBC t3 driver was unprepared to receive numbers with a localization format other than US English. To fix the problem, the JDBC t3 driver has a new connection property, weblogic.t3.doOraclI18nSetup. When this property is set to true, the t3 driver executes a query on the Oracle database to find the grouping and decimal characters used in the database. Then the t3 driver converts Strings to numbers correctly.

Here is some code to show how where to set the new property:

  Class.forName("weblogic.jdbc.t3.Driver").newInstance();
  // Set up properties for connecting to the DBMS
  Properties dbprops = new Properties();
  dbprops.put("user",                         "scott");
  dbprops.put("password",                     "tiger");
  dbprops.put("server",                       "DEMO20");

  Properties t3props = new Properties();
  t3props.put("weblogic.t3.dbprops",          dbprops);
  // Set the URL of WebLogic to create an embedded T3Client
  t3props.put("weblogic.t3.serverURL",       "t3://localhost:7001");
  t3props.put("weblogic.t3.driverClassName", "weblogic.jdbc.oci.Driver");
  t3props.put("weblogic.t3.driverURL",       "jdbc:weblogic:oracle");
  t3props.put("weblogic.t3.cacheRows",       "10");
  // Tell driver to expect non-US currency format
  t3props.put("weblogic.t3.doOracleI18nSetup,"true");

Converting localized numbers this way has a performance cost. An alternative with a lower performance cost is to set the environment variable NLS_NUMERIC_CHARACTERS to a string containing the group separator character and decimal separator characters in use in the database. This variable must be set in the environment of the process where you run the WebLogic Server. For example, if you are running the WebLogic Server on Windows NT and using an Oracle database with a French localized database, you would set the environment this way before you start the server:

  $ SET NLS_NUMERIC_CHARACTERS=.,

Modified the weblogic.jdbc.t3.Connection.refresh() method so that the client can immediately begin to use the connection after calling the refresh() method. Before this change, the client had to close the connection and reconnect, because the refresh() method cleared out the client's state information on the server.

Release 3.1.2

The PreparedStatement.setObject(int, Object, int) method, which converts its Object parameter to the type specified in the third parameter (an int), no longer fails when the Object type and the int type specified differ.

Release 3.1

Added two multitier properties for use when connecting via a connection pool with an embedded T3Client. Set these to a T3User username and password that matches a T3User on the access control list for the connection pool:
  props.put("weblogic.t3.user",      "joeuser");
  props.put("weblogic.t3.password",  "joespsswd");

Added support for Oracle Blob chunking with the new JDBC property weblogic.t3.blobChunkSize, for use with the jdbcKona/Oracle driver.

Added configuration properties that support shrinking the size of a connection pool in increments if the connections are unused after a configurable period of time. The command to shrink the pool can be exercised in code or with an weblogic.T3Admin command; permission for this action is controlled by a new ACL, "shrink," which -- like "reset" -- is available only to T3Users with administrative-level (system) privileges. New configuration properties are:
weblogic.jdbc.connectionPool.eng=\
       url=jdbc:weblogic:oracle,\
       driver=weblogic.jdbc.oci.Driver,\
       loginDelaySecs=1,\
       initialCapacity=4,\
       capacityIncrement=2,\
       maxCapacity=10,\
       allowShrinking=true,\
       shrinkPeriodMins=2,\
       props=user=SCOTT;password=tiger;server=demo
weblogic.allow.reserve.weblogic.jdbc.connectionPool.eng=\
       guest,joe,jill
weblogic.allow.shrink.weblogic.jdbc.connectionPool.eng=system

The default shrinkPeriod is 15 minutes and the minimum is 1 minute. The property allowShrinking is set by default to false for backward compatibility.

Release 3.0.4

Pool connections now cleaned up more politely for reuse.

Changed the way nested exceptions are serialized so that they are now treated as an exception instead of a more generic object. This affects JDBC drivers that throw exceptions that subclass SQLException and SQLWarning. In particular, this fixes a problem caused when a subclass of SQLException or SQLWarning doesn't have a public null constructor, which is required for serialization of generic objects.

Release 3.0 -- 1/29/98

With WebLogic release 3.0, you should have upgraded your use of WebLogic JDBC to the latest release of the 1.1 version of the Java Developers Kit. WebLogic no longer supports 1.0.2 universally; our 1.0.2 support is limited to client-side applets (using only WebLogic JDBC, RMI, Event, and T3Servlet services) that are run in either Microsoft IE 3.0.2 or later or Netscape 3.0 or later browsers. Running the WebLogic Server against JDK 1.0.2 is no longer supported, and running your WebLogic applications against a 1.0.2 JVM is also no longer supported.

Added two new Connection properties, name and description, to the WebLogic JDBC multitier driver to improve reporting in the WebLogic Console. (More on these properties)

Added support for access control lists.

Release 2.5.3 -- 11/3/97

Added performance enhancements to serialization in WebLogic and all its services, include WebLogic JDBC.

Release 2.5.2 -- 10/17/97

Fixed a problem with Float data types.

Release 2.5 -- 8/23/97

Added support for oopt(), Oracle functionality that allows a client to wait until resources become available, for WebLogic JDBC clients connecting to an Oracle database, with jdbcKona/Oracle. This support is a new extension to jdbcKona/Oracle and WebLogic JDBC.

Added support for JDBC Extended SQL. For more information, including examples, of WebLogic support for extended SQL in the jdbcKona drivers, see the Developers Guide, Overview of the jdbcKona native drivers.

Added support for Oracle's array fetches, which fetches a set number of rows on the first ResultSet.next() into memory, and uses that cache of rows for each subsequent call to next(). A call to next() will only cause another database operation each time the in-memory cache is exhausted.

Introduced internationalization support (support for the Oracle AL24UTFFSS codeset, also known as UTF-8). For more information, see the Developers Guide for jdbcKona/Oracle.

Release 2.4 -- 5/20/97

Newest releases of browsers from Netscape and Microsoft include support for java.sql.* in the client. We fully support java.sql.* in the browser. You will just need to upgrade your classes to use java.sql.* rather than xjava.sql.*.

Added support for double-buffered WebLogic JDBC fetches, for a dramatic improvement in query speed. As the T3Client executes a Statement, the first n rows (where n is the number of records to cache, according to the cacheRows property for the WebLogic JDBC Connection) are fetched to the WebLogic Server and stored in preparation for the first fetch on the T3Client. Each fetch on the client queues the next n rows on the WebLogic Server.

Changed usage for T3Client constructor. If you want to use java.sql.* (JDK 1.1) rather than xjava.sql.* (which is required if you must use JDK 1.0.2), you must set a flag in the T3Client constructor. (More information on clients, more information on upgrading to JDK 1.1) To indicate that you want to use java.sql.*, add the query parameter usexjava=false to the URL for the WebLogic Server in the T3Client constructor, as in this example:
  T3Client t3 = new T3Client("t3://localhost:7001?usexjava=false");

Made WebLogic JDBC Connections thread-safe.

Release 2.3.2 -- 3/18/97

Added functionality to allow you to set properties for a WebLogic JDBC Connection in a single URL that is passed to the DriverManager.getConnection() method. For more information, see the Developers Guide, Using URLs to set properties for a JDBC Connection.

Added functionality to allow a refreshing on members of a connection pool. To use this capability, place the execution of a SQL statement over the connection that cannot fail (for example, "select 1 from dual" for an Oracle DBMS) inside a try block, and refresh the connection after catching the SQLException. There is an example included in the distribution in examples/jdbc/t3/connectionpool.java. For more information, see the API reference notes in weblogic.jdbc.t3.Connection.

Added capability for an embedded T3Client, by setting the property "weblogic.t3.serverURL" to the java.util.Properties object. (More information) This property specifies the WebLogic Server to which the T3Client will connect. It is no longer necessary to create a T3Client or connect; the database connection creates the T3Client and connects for you. (If you need a reference to a T3Client for other purposes, you can still create the T3Client, connect, and disconnect as in the past.)

Changed two existing property names (previous versions will be supported indefinitely) to make the names more intuitive. These are illustrated in the example above. Changed:

Formerly Now
weblogic.t3.driver weblogic.t3.driverClassName
weblogic.t3.url weblogic.t3.driverURL

Fixed problem that was preventing exceptions on read from being propagated back to the client.

Fixed problem with clients detecting NULL return values in output parameters.

Fixed problem with ResultSet.getString().

Fixed problem with serializing doubles.

Fixed problem where successive calls to PreparedStatement.execute() caused a 'ResultSet already closed' error.

Release 2.3 -- 12/23/96

Added new pages to the T3Admin servlets for T3Client workspaces, T3Connections, and WebLogic JDBC Info.

Connection pools are now available to T3Clients. A Connection pool is a set of JDBC connections that are reserved for a particular WebLogic T3User or group of T3Users.

Added support for cached connections in the T3Client workspace. A cached connection remains open and available for client use; a client can disconnect and reconnect, and the connection is still available, without having the overhead of logging into the database again.

Release 2.2 -- 10/27/96

Introduced WebLogic workspace names and workspace IDs. State information for a T3Client is now saved in a named workspace in the WebLogic Server. A T3Client object can be instantiated, given a name, and then destroyed. A new T3Client can be instantiated and can retrieve the named state information when it reconnected to the WebLogic Server. Currently saved in the workspace are WebLogic JDBC connections, objects stored in the workspace cache, and T3Client parameter information, such as disconnect timeouts.

When you use WebLogic JDBC and the WebLogic Server on Windows NT with jdbcKona/Oracle to connect to an Oracle database, we require use of the Oracle 7.3 client libraries, since they provide thread safety, and the WebLogic Server is multithreaded. The Oracle 7.1 and 7.2 client libraries (not the server) are not threadsafe. Note that this requirement does not apply when the jdbcKona/Oracle driver is used in a two-tier environment, without WebLogic JDBC.

Added support for Oracle cursors as output parameters for stored procedures to WebLogic JDBC.

Added support for jdbcKona/Sybase extensions to WebLogic JDBC.

Added WebLogic JDBC-specific methods for Connection.cacheRows(). You can now set the cacheRows property on the Connection object to change cacheRows value for subsequent queries.

JDBC DriverManager logging in WebLogic is now controllable by the WebLogic Server administrator in the weblogic.properties file, through the use of two properties, weblogic.jdbc.logFile and weblogic.jdbc.logFileEnable. The first sets the name of the file to use for logs, and the second property enables and disables logging. When you enable JDBC logging, log information is collected into a single, per-WebLogic Server log file for all the the underlying two-tier jdbcKona drivers that are running in the WebLogic Server, as if DriverManager.setLogStream() was called.

Release 2.0.9 -- 9/9/96

Completed the API, with the addition of all DatabaseMetaData methods.

Improved performance eightfold for queries and stored procedures.

Simplified argument processing.

Please note changes in setting and passing java.util.Properties objects for WebLogic JDBC. Former syntax is still supported. (See Setting properties for connecting)

Release 2.0.7 -- 8/16/96

The xjava.sql.* packages in this distribution implement the JavaSoft 1.01 java.sql interfaces.

Release 2.0.6 -- 8/5/96

This is the first public beta release of WebLogic JDBC, the WebLogic multitier implementation of the JDBC API. WebLogic JDBC has been in limited beta release since late July.

 

Copyright © 2000 BEA Systems, Inc. All rights reserved.
Required browser: Netscape 4.0 or higher, or Microsoft Internet Explorer 4.0 or higher.
Last updated 04/07/1999