org.apache.myfaces.orchestra.connectionManager
Class ConnectionManagerDataSource

java.lang.Object
  extended by org.apache.myfaces.orchestra.connectionManager.ConnectionManagerDataSource
All Implemented Interfaces:
javax.sql.DataSource

public class ConnectionManagerDataSource
extends java.lang.Object
implements javax.sql.DataSource

Manage all borrowed connections and hand out DisconnectableConnection objects so that we can close them again after the HTTP request has been finished.

This datasource can be configured as a "wrapper" for a real datasource. When a connection is requested from this object, a proxy is returned that simply forwards all calls transparently to the real connection. This manager keeps track of all the Connections borrowed by each thread. At some point (eg from a servlet filter) this object can be asked to check for unreturned connections held by the current thread. If any exist then the real connection is returned to the underlying datasource and the proxy's connection reference is set to null. This ensures that a thread cannot leak real database connections.

Of course all code should return its connections; this is only a workaround/hack useful when the real problem cannot be fixed. This is particularly useful for JPA implementations that do not free their connection again after a lazy-init.

If a proxy's underlying connection has been returned to the database (either via the leak-detection, or by explicitly calling close) then invoking any method on the proxy will transparently cause a new connection to be retrieved from the underlying datasource. This means that a Connection returned by this datasource works somewhat differently than a normal one: for a normal connection, close() followed by prepareStatement() would cause an exception to be thrown, but works when this datasource is used.

See Also:
DisconnectableConnection

Constructor Summary
ConnectionManagerDataSource()
           
 
Method Summary
 java.sql.Connection getConnection()
          Return a proxy that wraps a connection of the underlying datasource.
 java.sql.Connection getConnection(java.lang.String username, java.lang.String password)
          Not supported.
 javax.sql.DataSource getDataSource()
          Return the underlying datasource for this wrapper.
 int getLoginTimeout()
           
 java.io.PrintWriter getLogWriter()
           
 boolean isWrapperFor(java.lang.Class iface)
          Always throws UnsupportedOperationException.
static void releaseAllBorrowedConnections()
          If the calling thread has allocated connections via this datasource, then return the underlying real connections to the underlying datasource.
 void setDataSource(javax.sql.DataSource dataSource)
          Set the underlying datasource via an explicit call.
 void setJndiName(java.lang.String jndiName)
          Specify that the underlying datasource should be retrieved via JNDI.
 void setLoginTimeout(int seconds)
           
 void setLogWriter(java.io.PrintWriter out)
           
 java.lang.Object unwrap(java.lang.Class iface)
          Always throws UnsupportedOperationException.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

ConnectionManagerDataSource

public ConnectionManagerDataSource()
Method Detail

releaseAllBorrowedConnections

public static void releaseAllBorrowedConnections()
If the calling thread has allocated connections via this datasource, then return the underlying real connections to the underlying datasource.

To code that holds references to the proxy connection returned by this datasource, this operation is generally transparent. They continue to hold a reference to the proxy, and if a method is ever called on that proxy in the future then the proxy will transparently allocate a new underlying Connection at that time.

This is expected to be called just before a thread is returned to a threadpool, eg via a ServletFilter just before returning from processing a request.


setDataSource

public void setDataSource(javax.sql.DataSource dataSource)
Set the underlying datasource via an explicit call. See also method setJndiName.


getDataSource

public javax.sql.DataSource getDataSource()
Return the underlying datasource for this wrapper.

If method setJndiName was used to specify the datasource, then it is retrieved from JNDI if necessary.

Throws:
java.lang.IllegalArgumentException - if neither setDataSource nor setJndiName was called.
java.lang.IllegalArgumentException - if an invalid jndi name was specified.

setJndiName

public void setJndiName(java.lang.String jndiName)
Specify that the underlying datasource should be retrieved via JNDI.


getConnection

public java.sql.Connection getConnection()
                                  throws java.sql.SQLException
Return a proxy that wraps a connection of the underlying datasource.

Specified by:
getConnection in interface javax.sql.DataSource
Throws:
java.sql.SQLException

getConnection

public java.sql.Connection getConnection(java.lang.String username,
                                         java.lang.String password)
                                  throws java.sql.SQLException
Not supported. Always throws UnsupportedOperationException.

Specified by:
getConnection in interface javax.sql.DataSource
Throws:
java.sql.SQLException

getLogWriter

public java.io.PrintWriter getLogWriter()
                                 throws java.sql.SQLException
Specified by:
getLogWriter in interface javax.sql.DataSource
Throws:
java.sql.SQLException

setLogWriter

public void setLogWriter(java.io.PrintWriter out)
                  throws java.sql.SQLException
Specified by:
setLogWriter in interface javax.sql.DataSource
Throws:
java.sql.SQLException

setLoginTimeout

public void setLoginTimeout(int seconds)
                     throws java.sql.SQLException
Specified by:
setLoginTimeout in interface javax.sql.DataSource
Throws:
java.sql.SQLException

getLoginTimeout

public int getLoginTimeout()
                    throws java.sql.SQLException
Specified by:
getLoginTimeout in interface javax.sql.DataSource
Throws:
java.sql.SQLException

unwrap

public java.lang.Object unwrap(java.lang.Class iface)
                        throws java.sql.SQLException
Always throws UnsupportedOperationException.

Note that this method was only introduced in java 1.6, and therefore cannot be implemented on platforms earlier than this without using reflection. Orchestra supports pre-1.6 JVMs, and this is a very rarely used method so currently no support is offered for this method.

Throws:
java.sql.SQLException

isWrapperFor

public boolean isWrapperFor(java.lang.Class iface)
                     throws java.sql.SQLException
Always throws UnsupportedOperationException. See method unwrap.

Throws:
java.sql.SQLException


Copyright © 2009 The Apache Software Foundation. All Rights Reserved.