11. The Server Class
Contents
11.1. Introduction
11.2. Creating a Server Object
11.1. Introduction
A Server object is created so multiple Database objects can share the same schema and connection pool. A Server object is associated with one or more schemas and manages all connection pools defined in its assigned schema. A Server also manages a pool of reusable Database objects. The Enterprise Edition global shared cache is maintained in the Server object and shared by all Database objects managed by the Server. Multiple Server objects may be created in order to maintain multiple global shared caches. A Server object also makes it simple for middleware based applications, such as those based on EJB or servlets, to obtain a Database object from a global shared location in order to perform persistence operations.
A Database pool is similar to a connection pool in that Database objects are pre-created and ready to be used by clients. Database objects in a pool are not permanently assigned a specific connection of a connection pool. Each time a method that requires access to the database is called, a Database object may be assigned a different connection object from the connection pool. So you may define a different number of initial and maximum number of Database and connection objects in each pool.
Although a Server manages all
connection pools, the connection pool itself is created by specifying the appropriate
parameters in the DB Configuration form using the mapping tool, or in a DBConfiguration
object at runtime. Therefore this
section will not deal with the creation of connection pools. For details please
see the The Advanced
Options Panel in section 5 of the
Mapping Tool Guide.
Note that Database pooling and Connection pooling are two different features that do not necessarily have to be used in conjunction with each other.
11.2. Creating a Server Object
A Server object can be created by
instantiating one directly using one of its public constructors or by using one
of its createServer() factory
methods. A Server object is created by passing it as
argument
the name of the schema containing all mapping information for the current
application. An array of schema names may also be passed to the constructor, in which case
the mappings defined in all the schemas are combined at runtime. All mapping schemas must
have been previously created using the mapping tool. It is also possible to define the
mapping schema in its entirety in code at runtime (i.e. without using the mapping tool). To do this
you must create your own subclass of the Server
class. See the vcontactdemo.engine.Server1
class in
the vcontactdemo sample application for an example.
Below is an example of how to create a Server
object:
com.objectmatter.bsf.Server srvr = new
com.objectmatter.bsf.Server("contactdemo");
The Server class also allows supplying a
DBConfiguration
object in some of its constructors. A DBConfiguration
object supplied at runtime overrides the DB Configuration information defined
using the mapping tool. This is useful if the application determines the
database connection parameters at runtime, instead of at design time. Below is
an example of usage:
DBConfiguration dbConfig = new DBConfiguration("default");
dbConfig.setExposed(true);
dbConfig.setDBURL("jdbc:odbc:Contact");
Server srvr = new com.objectmatter.bsf.Server("contactdemo", dbConfig);
See the API Reference for the com.objectmatter.bsf.mapping.schema.DBConfiguration
class for additional details.
Constructors are also provided so the Database pool parameters can be specified during instantiation. These include the initial and maximum number of Database objects in the pool, as well as an optional timeout period and timeout threshold. Below is the formal definition of each of the Database pool parameters that can be passed as arguments to the constructors:
initNoDatabases initial number of Database objects to be created in the pool.
The default is one. maxNoDatabases maximum number of Database objects, or 0 for unlimited. If an attempt is made to obtain a Database object when all objects in the pool are in use and the maximum number has been reached, a
BOMaxDatabasesReachedException will be thrown. The default is zero.dbPoolTimeout Database pool time-out period in msec. This is the amount of time that a client will wait to obtain a free Database object from the pool if the max number of Databases in the pool is reached. If a Database object does not become free during this wait period, the client will receive a
BOMaxDatabasesReachedException. A value of zero, the default, means that the client does not wait.timeoutThreshold number of Databases in the pool required for the timeout period to become effective when no more Databases are available but before attempting to add a new Database to the pool. The default is zero. This setting is only meaningful if
dbPoolTimeout is greater than zero. If
maxNoDatabases is greater than zero and
timeoutThreshold is zero, then the timeout will apply only when
maxNoDatabases is reached. If maxNoDatabases is greater than zero and
timeoutThreshold is greater than zero but less than
maxNoDatabases, then the timeout will apply at the
timeoutThreshold but before maxNoDatabases is reached, so VBSF will wait for a Database to become free during the timeout period and add a new one to the pool only if a Database did not become free during the timeout period. If
maxNoDatabases is zero (unlimited) and
timeoutThreshold is greater than zero, then when the number of Databases in the pool reaches
timeoutThreshold, VBSF will wait for
a Database to become free before adding a new one to the pool. This last setting allows an application to ensure that Databases never run out while still controlling the pool growth by means of forcing a wait period before allocating a new Database to the pool.The static createServer() factory
method can be used instead of the new
operator to create a 'named' Server
object. This allows creating one or more shared named Server objects, each
potentially associated with a different schema and/or connection pool. Any
thread within your application can then get a reference to a Server
object by passing its name to the static getServer()
method. The example below creates a Server object
utilizing the contactdemo.schema, and a Database object pool with 5 initial
Database objects, a maximum of 25 Database objects. a 100msec timeout period and
a timeout threshold of 10 Database objects:
Server srvr = Server.createServer("MyServer","contactdemo",5,25,100,10);
11.3. Database Object Pool Parameters
The table below provides several examples of different parameters that may be
specified for the Database pool and
provides more details as to how VBSF interprets those parameters:
initNoDatabases, |
VBSF Behavior |
| 1,0,0,0 | One initial Database object is created in the pool and the pool can grow to an unlimited number of objects. No timeout or timeout threshold is specified. This is the default setting if no pool parameters are specified. |
| 5,25,0,0 | Five
initial Database objects are created in the pool and the pool can grow to
25 objects. Once the pool size limit of 25 is reached the client will
receive a BOMaxDatabasesReachedException.
Additional clients that request connections will receive the same
exception until a connection becomes available again. No timeout or
timeout threshold is specified. |
| 5,25,100,0 | Five
initial Database objects are created in the pool and the pool can grow to
25 objects. Once the pool size limit of 25 is reached the client will wait
for 100msec. If a connection becomes available within 100msec the client
will receive the connection. If no connection becomes available the client
will receive a BOMaxDatabasesReachedException.
No timeout threshold is specified. |
| 5,25,100,10 | Five
initial Database objects are created in the pool and the pool can grow to
25 objects. Once the pool size reaches 10 objects (the timeout threshold)
a client will wait for 100msec to see if an existing in-use connection
becomes available. If a connection
becomes available within 100msec the client will receive that connection.
If no connection becomes available during the 100msec wait period a new
connection will be added to the pool and returned to the client.
Once the pool size limit
of 25 is reached the client will wait for 100msec. If a connection becomes
available within 100msec the client will receive the connection. If no
connection becomes available the client will receive a |
| 5,0,100,10 | Five initial Database objects are created in the pool and the pool can grow to an unlimited number of objects. Once the pool size reaches 10 objects (the timeout threshold) a client will wait for 100msec to see if an existing in-use connection becomes available. If a connection becomes available within 100msec the client will receive that connection. If no connection becomes available during the 100msec wait period a new connection will be added to the pool and returned to the client. Since the pool can grow forever this setting allows an application to ensure that Databases never run out while still controlling the pool growth by means of forcing a wait period before allocating a new Database to the pool. |
Determining the correct pool parameters for an application is based a lot on
trial and error. Start with values that appear appropriate for the expected
application load and monitor the response of the system under different loads.
You can monitor the status of the Database
and connection pools by turning on VBSF debugging at the MONITOR level. The
number of concurrent connections that an application in production will require
will usually be far less than the number of concurrent Databases.
This is because connections are used for a much shorter time span than Databases.
As a result, you should set the connection pool and Database
pool parameters accordingly.
11.4. Using the Database Object Pool
One issue that arises when using VBSF in EJB, servlet and other middleware
based environments is where
should a bean or servlet get a Database object from in order to perform persistence
operations. By using the static factory method in the Server
class that allows creating a named Server
object your application can easily obtain a reference to a Database
from within any thread or location in your application. For example, if a Server
object is created as shown below:
Server.createServer("MyServer","contactdemo.schema",5,25,0,0);
Then, inside your bean or servlet you can obtain a free Database object from the
pool by doing:
Database db = Server.getServer("MyServer").getDatabase();
A Database is assigned to a client via the
Server.getDatabase() method, and the client must call the
Database.close() method when done to release it back to the pool.
This facility is very useful in servlet and EJB environments because Database objects are not multithreaded and thus client threads must be assigned different Database objects. Note however that a
Server object is fully multithreaded.
When your bean or servlet is done with the Database object, it should close it to return it
back to the pool:
db.close(); //return Database to pool
Database objects obtained from a Server
object are already opened and ready for use if a connection pool or login parameters
have been predefined in the mapping tool DB Configuration, or via a DBConfiguration
object passed to the Server constructor.
If this is not the case, then the open() method
must be called with applicable URL, username and password parameters, or with a
JDBC connection object. Note that if you are calling open() you cannot not define a VBSF connection
pool. For details on how to set up VBSF to accept connections from an external pool see the section titled
'Using the Application Server's Connection
Pool' in section 12 'EJB, Servlet and Other
Middleware Environments'.
A Server object can also maintain Database objects by thread via the
Server.getDatabaseForThread() method. This method returns the Database object assigned to the current thread. If no Database object has been assigned to the current thread then the next available one is retrieved from the Database pool and returned. Subsequent calls to this method from the same thread
return the same Database object. This avoids having to store the Database object
in a local variable in a bean to allow further access to it.