com.mysql.jdbc
Class LoadBalancingConnectionProxy

java.lang.Object
  extended by com.mysql.jdbc.LoadBalancingConnectionProxy
All Implemented Interfaces:
PingTarget, java.lang.reflect.InvocationHandler
Direct Known Subclasses:
FailoverConnectionProxy

public class LoadBalancingConnectionProxy
extends java.lang.Object
implements java.lang.reflect.InvocationHandler, PingTarget

An implementation of java.sql.Connection that load balances requests across a series of MySQL JDBC connections, where the balancing takes place at transaction commit. Therefore, for this to work (at all), you must use transactions, even if only reading data. This implementation will invalidate connections that it detects have had communication errors when processing a request. Problematic hosts will be added to a global blacklist for loadBalanceBlacklistTimeout ms, after which they will be removed from the blacklist and made eligible once again to be selected for new connections. This implementation is thread-safe, but it's questionable whether sharing a connection instance amongst threads is a good idea, given that transactions are scoped to connections in JDBC.


Nested Class Summary
protected  class LoadBalancingConnectionProxy.ConnectionErrorFiringInvocationHandler
           
 
Field Summary
static java.lang.String BLACKLIST_TIMEOUT_PROPERTY_KEY
           
protected  MySQLConnection currentConn
           
protected  java.util.List<java.lang.String> hostList
           
protected  java.util.Map<java.lang.String,ConnectionImpl> liveConnections
           
 
Constructor Summary
LoadBalancingConnectionProxy(java.util.List<java.lang.String> hosts, java.util.Properties props)
          Creates a proxy for java.sql.Connection that routes requests between the given list of host:port and uses the given properties when creating connections.
 
Method Summary
 boolean addHost(java.lang.String host)
           
 void addToGlobalBlacklist(java.lang.String host)
           
 void addToGlobalBlacklist(java.lang.String host, long timeout)
           
 ConnectionImpl createConnectionForHost(java.lang.String hostPortSpec)
          Creates a new physical connection for the given host:port and updates required internal mappings and statistics for that connection.
protected  LoadBalancingConnectionProxy.ConnectionErrorFiringInvocationHandler createConnectionProxy(java.lang.Object toProxy)
           
(package private)  void dealWithInvocationException(java.lang.reflect.InvocationTargetException e)
           
 void doPing()
           
 long getActivePhysicalConnectionCount()
           
 long getConnectionGroupProxyID()
           
 java.lang.String getCurrentActiveHost()
           
 long getCurrentTransactionDuration()
           
 java.util.Map<java.lang.String,java.lang.Long> getGlobalBlacklist()
           
 long getLastUsed()
           
 long getTotalPhysicalConnectionCount()
           
 long getTransactionCount()
           
 boolean inTransaction()
           
(package private)  void invalidateCurrentConnection()
          Closes current connection and removes it from required mappings.
 java.lang.Object invoke(java.lang.Object proxy, java.lang.reflect.Method method, java.lang.Object[] args)
           
 java.lang.Object invoke(java.lang.Object proxy, java.lang.reflect.Method method, java.lang.Object[] args, boolean swapAtTransactionBoundary)
          Proxies method invocation on the java.sql.Connection interface, trapping "close", "isClosed" and "commit/rollback" (to switch connections for load balancing).
 boolean isGlobalBlacklistEnabled()
           
protected  void pickNewConnection()
          Picks the "best" connection to use for the next transaction based on the BalanceStrategy in use.
(package private)  java.lang.Object proxyIfInterfaceIsJdbc(java.lang.Object toProxy, java.lang.Class clazz)
          Recursively checks for interfaces on the given object to determine if it implements a java.sql interface, and if so, proxies the instance so that we can catch and fire SQL errors.
 void removeHost(java.lang.String host)
           
 void removeHostWhenNotInUse(java.lang.String host)
           
 boolean shouldExceptionTriggerFailover(java.sql.SQLException ex)
           
protected  void syncSessionState(Connection initial, Connection target)
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

BLACKLIST_TIMEOUT_PROPERTY_KEY

public static final java.lang.String BLACKLIST_TIMEOUT_PROPERTY_KEY
See Also:
Constant Field Values

currentConn

protected MySQLConnection currentConn

hostList

protected java.util.List<java.lang.String> hostList

liveConnections

protected java.util.Map<java.lang.String,ConnectionImpl> liveConnections
Constructor Detail

LoadBalancingConnectionProxy

LoadBalancingConnectionProxy(java.util.List<java.lang.String> hosts,
                             java.util.Properties props)
                       throws java.sql.SQLException
Creates a proxy for java.sql.Connection that routes requests between the given list of host:port and uses the given properties when creating connections.

Parameters:
hosts -
props -
Throws:
java.sql.SQLException
Method Detail

createConnectionForHost

public ConnectionImpl createConnectionForHost(java.lang.String hostPortSpec)
                                       throws java.sql.SQLException
Creates a new physical connection for the given host:port and updates required internal mappings and statistics for that connection.

Parameters:
hostPortSpec -
Returns:
Throws:
java.sql.SQLException

dealWithInvocationException

void dealWithInvocationException(java.lang.reflect.InvocationTargetException e)
                           throws java.sql.SQLException,
                                  java.lang.Throwable,
                                  java.lang.reflect.InvocationTargetException
Parameters:
e -
Throws:
java.sql.SQLException
java.lang.Throwable
java.lang.reflect.InvocationTargetException

invalidateCurrentConnection

void invalidateCurrentConnection()
                           throws java.sql.SQLException
Closes current connection and removes it from required mappings.

Throws:
java.sql.SQLException

invoke

public java.lang.Object invoke(java.lang.Object proxy,
                               java.lang.reflect.Method method,
                               java.lang.Object[] args)
                        throws java.lang.Throwable
Specified by:
invoke in interface java.lang.reflect.InvocationHandler
Throws:
java.lang.Throwable

invoke

public java.lang.Object invoke(java.lang.Object proxy,
                               java.lang.reflect.Method method,
                               java.lang.Object[] args,
                               boolean swapAtTransactionBoundary)
                        throws java.lang.Throwable
Proxies method invocation on the java.sql.Connection interface, trapping "close", "isClosed" and "commit/rollback" (to switch connections for load balancing).

Throws:
java.lang.Throwable

pickNewConnection

protected void pickNewConnection()
                          throws java.sql.SQLException
Picks the "best" connection to use for the next transaction based on the BalanceStrategy in use.

Throws:
java.sql.SQLException

proxyIfInterfaceIsJdbc

java.lang.Object proxyIfInterfaceIsJdbc(java.lang.Object toProxy,
                                        java.lang.Class clazz)
Recursively checks for interfaces on the given object to determine if it implements a java.sql interface, and if so, proxies the instance so that we can catch and fire SQL errors.

Parameters:
toProxy -
clazz -
Returns:

createConnectionProxy

protected LoadBalancingConnectionProxy.ConnectionErrorFiringInvocationHandler createConnectionProxy(java.lang.Object toProxy)

doPing

public void doPing()
            throws java.sql.SQLException
Specified by:
doPing in interface PingTarget
Throws:
java.sql.SQLException

addToGlobalBlacklist

public void addToGlobalBlacklist(java.lang.String host,
                                 long timeout)

addToGlobalBlacklist

public void addToGlobalBlacklist(java.lang.String host)

isGlobalBlacklistEnabled

public boolean isGlobalBlacklistEnabled()

getGlobalBlacklist

public java.util.Map<java.lang.String,java.lang.Long> getGlobalBlacklist()

shouldExceptionTriggerFailover

public boolean shouldExceptionTriggerFailover(java.sql.SQLException ex)

removeHostWhenNotInUse

public void removeHostWhenNotInUse(java.lang.String host)
                            throws java.sql.SQLException
Throws:
java.sql.SQLException

removeHost

public void removeHost(java.lang.String host)
                throws java.sql.SQLException
Throws:
java.sql.SQLException

addHost

public boolean addHost(java.lang.String host)

getLastUsed

public long getLastUsed()

inTransaction

public boolean inTransaction()

getTransactionCount

public long getTransactionCount()

getActivePhysicalConnectionCount

public long getActivePhysicalConnectionCount()

getTotalPhysicalConnectionCount

public long getTotalPhysicalConnectionCount()

getConnectionGroupProxyID

public long getConnectionGroupProxyID()

getCurrentActiveHost

public java.lang.String getCurrentActiveHost()

getCurrentTransactionDuration

public long getCurrentTransactionDuration()

syncSessionState

protected void syncSessionState(Connection initial,
                                Connection target)
                         throws java.sql.SQLException
Throws:
java.sql.SQLException