支持失效转移的数据源

package spring.datasource;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Map;

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.jdbc.datasource.lookup.DataSourceLookup;
import org.springframework.util.Assert;

/**
 * <p>
 * <b>FailoverDataSource</b>支持失效转移的数据源
 * </p>
 *
 *
 */
public class FailoverDataSource extends AbstractRoutingDataSource {

    // private Map targetDataSources = null;

    private Object[] targetDataSourcesKeys = null;

    private static final ThreadLocal<Object> contextHolder = new ThreadLocal<Object>();

    public static void setCurrentLookupKeyIndex(Integer currentLookupKeyIndex) {
        Assert.notNull(currentLookupKeyIndex,
                "current LookupKey cannot be null");
        contextHolder.set(currentLookupKeyIndex);
    }

    public static Integer getCurrentLookupKeyIndex() {
        Integer i = (Integer) contextHolder.get();
        if (i == null) {
            setCurrentLookupKeyIndex(0);
            return new Integer(0);
        } else {
            return i;
        }
    }

    public static void clearCurrentLookupKeyIndex() {
        contextHolder.remove();
    }

    /*
     * (重载方法)
     *
     * @see org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource#determineCurrentLookupKey()
     */
    @Override
    protected Object determineCurrentLookupKey() {
        return targetDataSourcesKeys[getCurrentLookupKeyIndex().intValue()];
    }

    /*
     * (重载方法)
     *
     * @see org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource#getConnection()
     */
    @Override
    public Connection getConnection() throws SQLException {
        int i = 0;
        do {
            try {
                if (logger.isDebugEnabled())
                    logger.debug("Datasource connect ...["
                            + determineCurrentLookupKey() + "]");
                // 尝试获取
                return determineTargetDataSource().getConnection();
            } catch (SQLException e) {
                if (i >= targetDataSourcesKeys.length)
                    throw e;
                if (logger.isInfoEnabled())
                    logger.info("Datasource connect failed!["
                            + determineCurrentLookupKey() + "]", e);
            }

            // 获取连接失败,切换数据库
            i++;
            if (i < targetDataSourcesKeys.length)
                setCurrentLookupKeyIndex(i);
            else
                return determineTargetDataSource().getConnection();
        } while (i < targetDataSourcesKeys.length);
        return determineTargetDataSource().getConnection();
    }

    /*
     * (重载方法)
     *
     * @see org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource#setDataSourceLookup(org.springframework.jdbc.datasource.lookup.DataSourceLookup)
     */
    @Override
    public void setDataSourceLookup(DataSourceLookup dataSourceLookup) {
        // TODO Auto-generated method stub
        super.setDataSourceLookup(dataSourceLookup);
    }

    /*
     * (重载方法)
     *
     * @see org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource#setDefaultTargetDataSource(java.lang.Object)
     */
    @Override
    public void setDefaultTargetDataSource(Object defaultTargetDataSource) {
        // TODO Auto-generated method stub
        super.setDefaultTargetDataSource(defaultTargetDataSource);
    }

    /*
     * (重载方法)
     *
     * @see org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource#setTargetDataSources(java.util.Map)
     */
    @Override
    public void setTargetDataSources(Map targetDataSources) {
        // this.targetDataSources = targetDataSources;
        this.targetDataSourcesKeys = targetDataSources.keySet().toArray();
        setCurrentLookupKeyIndex(0);
        super.setTargetDataSources(targetDataSources);
    }

}

 

 

 

<bean id="dataSource1"
        class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiName" value="${dataSource.jndiName}" />
        <property name="resourceRef" value="true"></property>
    </bean>
    <bean id="dataSource2"
        class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName"
            value="${jdbc.driverClassName}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
    </bean>
    <bean id="dataSource3"
        class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName"
            value="${jdbc.driverClassName1}" />
        <property name="url" value="${jdbc.url1}" />
        <property name="username" value="${jdbc.username1}" />
        <property name="password" value="${jdbc.password1}" />
    </bean>
    <util:map id="dataSources">
        <entry key="ds1" value-ref="dataSource1" />
        <entry key="ds2" value-ref="dataSource2" />
        <entry key="ds3" value-ref="dataSource3" />
    </util:map>
    <bean id="dataSourceLookup"
        class="org.springframework.jdbc.datasource.lookup.MapDataSourceLookup">
        <constructor-arg>
            <ref bean="dataSources" />
        </constructor-arg>
    </bean>
    <bean id="dataSource"
        class="com.spring.datasource.FailoverDataSource">
        <property name="defaultTargetDataSource" ref="dataSource1" />
        <property name="targetDataSources" ref="dataSources" />
        <property name="dataSourceLookup" ref="dataSourceLookup" />
    </bean>

    <!-- Transaction manager for a single JDBC DataSource -->
    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

你可能感兴趣的:(apache,spring,sql,bean,jdbc)