2012-03-13 3 views
1

Мы работаем над веб-приложением Spring, где ключом к бизнесу является высокая доступность. Hibernate - это ORM, а MySQL - это БД, которая используется. Наша архитектура заставляет нас иметь следующий механизм.Используйте запасной источник данных для Hibernate весной

  • Webapp сначала пытается подключиться к основному серверу MySQL.
  • Если это не удается, он подключается к вторичному серверу MySQL, который в основном не синхронизирован с данными.
  • Webapp должен знать, с каким сервером 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 для подключения к резервному источнику данных, когда первичный источник данных недоступен?

+0

* Может быть * это будет полезно: http://ha-jdbc.sourceforge.net –

+0

не кажется ( –

ответ

0

Этот вид трюков должен выполняться на стороне MySQL не на веб-сервере. Например, кластер MySQL может справиться с этим.

Больше информации здесь:

-http: //www.mysql.com/products/cluster/

-http: //en.wikipedia.org/wiki/MySQL_Cluster

ОБНОВЛЕНИЕ:

Итак, посмотрите здесь -> org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource. Создайте пользовательскую реализацию, которая переопределяет метод getConnection() и getConnection (имя пользователя String, пароль String). Оберните их, поймав SQLException, и если это произойдет, выберите другой источник данных.

+0

Я знаю, что это неправильно .. но наша нынешняя архитектура заставляет нас иметь вышеуказанный механизм :(Мы застряли со старой архитектурой и не можем двигаться немедленно !! –

1

, если настроить источник данных в качестве 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> 
+0

Спасибо, что решает первую часть. У нас есть возможность проверить, вернулся ли файл defaultDataSource и подключиться к нему? –

+0

hmmm, вы можете создать таблицу, которая позволяет говорить 'TDBVERSION', которая содержит только одну строку, независимо от того, abase является резервным или нет. и, запросив «TDBVERSION», ваша система будет знать, что использует резервное копирование или нет. – dursun

Смежные вопросы