java - 在 Spring 中使用 Hibernate 的后备数据源

标签 java database spring hibernate datasource

我们正在开发一个基于 Spring 的 Web 应用程序,其中业务的关键是高可用性。 Hibernate 是 ORM,MySQL 是使用的 DB。我们的架构迫使我们拥有以下机制。

  • Web 应用程序首先尝试连接到主 MySQL 服务器。
  • 如果失败,它将连接到辅助 MySQL 服务器,该服务器基本上与数据不同步。
  • Web 应用程序需要知道它连接到哪个 MySQL 服务器,因为我们希望在用户使用辅助服务器时通知用户。
  • 一旦与主设备重新建立连接,就必须将连接从辅助设备切换到主设备。

我陷入了第一阶段。我无法找到如何引导 Spring/Hibernate 使用多个数据库服务器。

这是当前的配置文件(删除不需要的内容):

 <?xml  version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jee="http://www.springframework.org/schema/jee" xmlns:lang="http://www.springframework.org/schema/lang"
    xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
        http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">


    <context:annotation-config />

    <context:component-scan base-package="com.smartshop" />

    <bean
        class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />


    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/primarydb" />
        <property name="username" value="username" />
        <property name="password" value="password" />
        <property name="maxIdle" value="10" />
        <property name="maxActive" value="100" />
        <property name="maxWait" value="10000" />
        <property name="validationQuery" value="select 1" />
        <property name="testOnBorrow" value="false" />
        <property name="testWhileIdle" value="true" />
        <property name="timeBetweenEvictionRunsMillis" value="1200000" />
        <property name="minEvictableIdleTimeMillis" value="1800000" />
        <property name="numTestsPerEvictionRun" value="5" />
        <property name="defaultAutoCommit" value="false" />
    </bean>


    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation">
            <value>/WEB-INF/hibernate.cfg.xml</value>
        </property>
        <property name="configurationClass">
            <value>org.hibernate.cfg.AnnotationConfiguration</value>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.show_sql">false</prop>
            </props>
        </property>
    </bean>

    <tx:annotation-driven />

    <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

    <bean
        class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor"
        name="openSessionInViewInterceptor">
        <property name="sessionFactory" ref="sessionFactory"></property>
        <property name="flushMode">
            <bean
                id="org.springframework.orm.hibernate3.HibernateAccessor.FLUSH_AUTO"
                class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean" />
        </property>
    </bean>

    <bean id="handlerMapping"
        class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
        <property name="interceptors">
            <list>
                <ref bean="localeChangeInterceptor" />
                <ref bean="openSessionInViewInterceptor" />
            </list>
        </property>
    </bean>

有没有办法定义 Spring 在主数据源无法访问时连接到备份数据源?

最佳答案

如果将数据源配置为 jndi 数据源,则可以使用以下配置

<bean id="dataSource"
    class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" ref="datasourceJNDIName" />
    <property name="defaultObject" ref="fallBackDataSource" />
</bean>

<!-- fall back datasource if JNDI look up of main datasource fails -->
<bean id="fallBackDataSource"
    class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" ref="datasourceJNDIName-2" />
</bean>

关于java - 在 Spring 中使用 Hibernate 的后备数据源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9678978/

相关文章:

java - 如何将静态jtable限制更改为动态(静态对象数组更改为动态)

php - JQGrid:通过post获取JQGrid中的多个选中行值

java - 从 Spring Controller 加载 CSS

java - Android 设备上的 PowerManager.WakeLock

java - 调整 javafx 形状位置的大小而不缩放它们

java - 如何获取类加载器的目录信息?

ruby - Datamapper,定义自己的对象方法,怎么样?

ruby-on-rails - Rails chart.js 数据 CoffeeScript

java - 使用 TestExecutionListener 时 Spring 测试注入(inject)不起作用

java - thymeleaf th :each filtered with th:if