Things can get more complicated when we use a J2EE server. Normally, a
prepared statement is associated with a single database connection. When the
connection is closed, the preparedstatement is discarded. Normally, a fat
client application would get a database connection and then hold it for its
lifetime. It would also create all prepared statements eagerly or lazily. Eagerly means that they are all created at once
when the application starts. Lazily means
that they are created as they are used. An eager approach gives a delay when
the application starts but once it starts then it performs optimally. A lazy
approach gives a fast start but as the application runs, the prepared
statements are created when they are first used by the application. This gives
an uneven performance until all statements are prepared but the application
eventually settles and runs as fast as the eager application. Which is best
depends on whether you need a fast start or even performance.
The problem with a
J2EE application is that it can't work like this. It only keeps a connection
for the duration of the request. This means that it must create the prepared
statements every time the request is executed. This is not as efficient as the
fat client approach where the prepared statements are created once, rather than
on every request. J2EE vendors have noticed this and designed connection
pooling to avoid this performance disadvantage.
When the J2EE server
gives your application a connection, it isn't giving you the actual connection;
you're getting a wrapper. You can verify this by looking at the name of the
class for the connection you are given. It won't be a database JDBC connection,
it'll be a class created by your application server. Normally, if you called
close on a connection then the jdbc driver closes the connection. We want the
connection to be returned to the pool when close is called by a J2EE
application. We do this by making a proxy jdbc connection class that looks like
a real connection. It has a reference to the actual connection. When we invoke
any method on the connection then the proxy forwards the call to the real
connection. But, when we call methods such as close instead of calling close on
the real connection, it simply returns the connection to the connection pool
and then marks the proxy connection as invalid so that if it is used again by
the application we'll get an exception.
Wrapping is very
useful as it also helps J2EE application server implementers to add support for
prepared statements in a sensible way. When an application calls
Connection.prepareStatement, it is returned a PreparedStatement object by the
driver. The application then keeps the handle while it has the connection and
closes it before it closes the connection when the request finishes. However,
after the connection is returned to the pool and later reused by the same, or
another application, , then ideally, we want the same PreparedStatement to be
returned to the application.
No comments:
Post a Comment