• SSH框架系列:Spring配置多个数据源


     

    分类: 【java】

    1.问题的引入

             对于普通的SSH框架而言,一般配置一个数据源,一个SessionFactory,一个事务管理和对应的ProxyCreate。那么当项目需要操作多个数据库时,如何配置呢?

    方案1

    配置2个数据源,2个对应的SessionFactory,2个事务等。Spring的配置如下:

    [html] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. <?xml version="1.0" encoding="UTF-8"?>  
    2. <beans xmlns="http://www.springframework.org/schema/beans"  
    3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"  
    4.     xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"  
    5.     xsi:schemaLocation="http://www.springframework.org/schema/beans  
    6.     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
    7.     http://www.springframework.org/schema/tx   
    8.     http://www.springframework.org/schema/tx/spring-tx-3.0.xsd  
    9.     http://www.springframework.org/schema/aop  
    10.     http://www.springframework.org/schema/aop/spring-aop-3.0.xsd  
    11.     http://www.springframework.org/schema/context  
    12.     http://www.springframework.org/schema/context/spring-context-3.0.xsd">  
    13.     <!-- 引入datasource配置文件 -->  
    14.     <context:property-placeholder location="classpath:datasource.properties" />  
    15.     <!--创建mysql jdbc数据源 -->  
    16.     <bean id="mysqlDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"  
    17.         destroy-method="close">  
    18.         <property name="driverClass" value="${jdbc.mysql.driver}" />  
    19.         <property name="jdbcUrl" value="${jdbc.mysql.url}" />  
    20.         <property name="user" value="${jdbc.mysql.username}" />  
    21.         <property name="password" value="${jdbc.mysql.password}" />  
    22.         <!-- 指定连接数据库连接池的最小连接数 -->  
    23.         <property name="minPoolSize" value="10" />  
    24.         <!-- 指定连接数据库连接池的最大连接数 -->  
    25.         <property name="maxPoolSize" value="30" />  
    26.         <!-- 指定连接数据库连接池的连接的最大空闲时间 -->  
    27.         <property name="maxIdleTime" value="1800" />  
    28.         <property name="acquireIncrement" value="2" />  
    29.         <property name="maxStatements" value="0" />  
    30.         <!-- 指定连接数据库连接池的初始化连接数 -->  
    31.         <property name="initialPoolSize" value="2" />  
    32.         <property name="idleConnectionTestPeriod" value="1800" />  
    33.         <!-- 当连接失败时,尝试重新连接的次数 -->  
    34.         <property name="acquireRetryAttempts" value="30" />  
    35.         <property name="breakAfterAcquireFailure" value="true" />  
    36.         <property name="testConnectionOnCheckout" value="false" />  
    37.     </bean>  
    38.     <!--创建oracle jdbc数据源 -->  
    39.     <bean id="oracleDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"  
    40.         destroy-method="close">  
    41.         <property name="driverClass" value="${jdbc.oracle.driver}" />  
    42.         <property name="jdbcUrl" value="${jdbc.oracle.url}" />  
    43.         <property name="user" value="${jdbc.oracle.username}" />  
    44.         <property name="password" value="${jdbc.oracle.password}" />  
    45.         <!-- 指定连接数据库连接池的最小连接数 -->  
    46.         <property name="minPoolSize" value="10" />  
    47.         <!-- 指定连接数据库连接池的最大连接数 -->  
    48.         <property name="maxPoolSize" value="30" />  
    49.         <!-- 指定连接数据库连接池的连接的最大空闲时间 -->  
    50.         <property name="maxIdleTime" value="1800" />  
    51.         <property name="acquireIncrement" value="2" />  
    52.         <property name="maxStatements" value="0" />  
    53.         <!-- 指定连接数据库连接池的初始化连接数 -->  
    54.         <property name="initialPoolSize" value="2" />  
    55.         <property name="idleConnectionTestPeriod" value="1800" />  
    56.         <!-- 当连接失败时,尝试重新连接的次数 -->  
    57.         <property name="acquireRetryAttempts" value="1" />  
    58.         <property name="breakAfterAcquireFailure" value="true" />  
    59.         <property name="testConnectionOnCheckout" value="false" />  
    60.     </bean>  
    61.     <!-- 创建MysqlSessionFactory-->  
    62.     <bean id="mysqlSessionFactory"  
    63.         class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">  
    64.         <property name="dataSource" ref="mysqlDataSource" />  
    65.         <property name="hibernateProperties">  
    66.             <props>  
    67.                 <prop key="hibernate.show_sql">true</prop>  
    68.                 <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>  
    69.                 <prop key="current_session_context_class">thread</prop>  
    70.             </props>  
    71.         </property>  
    72.         <property name="mappingResources">  
    73.             <list>  
    74.                 <value>edu/njupt/zhb/model/mysql/Student.hbm.xml</value>  
    75.             </list>  
    76.         </property>  
    77.     </bean>  
    78.   
    79.     <!-- 创建OracleSessionFactory-->  
    80.     <bean id="oracleSessionFactory"  
    81.         class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">  
    82.         <property name="dataSource" ref="oracleDataSource" />  
    83.         <property name="hibernateProperties">  
    84.             <props>  
    85.                 <prop key="hibernate.show_sql">true</prop>  
    86.                 <prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>  
    87.                 <prop key="current_session_context_class">thread</prop>  
    88.             </props>  
    89.         </property>  
    90.         <property name="mappingResources">  
    91.             <list>  
    92.                 <value>edu/njupt/zhb/model/oracle/Student.hbm.xml</value>  
    93.             </list>  
    94.         </property>  
    95.     </bean>  
    96.       
    97.     <!-- 配置Mysql事务 -->  
    98.     <bean id="mysqlTransactionManager"  
    99.         class="org.springframework.orm.hibernate4.HibernateTransactionManager">  
    100.         <property name="sessionFactory">  
    101.             <ref local="mysqlSessionFactory" />  
    102.         </property>  
    103.     </bean>  
    104.      <!--Mysql hibernate4必须配置为开启事务 否则 getCurrentSession()获取不到-->  
    105.     <bean id="mysqlTransactionInterceptor"  
    106.         class="org.springframework.transaction.interceptor.TransactionInterceptor">  
    107.         <property name="transactionManager">  
    108.             <ref local="mysqlTransactionManager" />  
    109.         </property>  
    110.         <property name="transactionAttributes">  
    111.             <props>  
    112.                 <prop key="register">PROPAGATION_REQUIRED</prop>  
    113.                 <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>  
    114.                 <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>  
    115.                 <prop key="select*">PROPAGATION_REQUIRED,readOnly</prop>  
    116.                 <prop key="query*">PROPAGATION_REQUIRED,readOnly</prop>  
    117.                 <prop key="sync*">PROPAGATION_REQUIRED</prop>  
    118.                 <prop key="finish*">PROPAGATION_REQUIRED</prop>  
    119.                 <prop key="add*">PROPAGATION_REQUIRED</prop>  
    120.                 <prop key="insert*">PROPAGATION_REQUIRED</prop>  
    121.                 <prop key="edit*">PROPAGATION_REQUIRED</prop>  
    122.                 <prop key="update*">PROPAGATION_REQUIRED</prop>  
    123.                 <prop key="save*">PROPAGATION_REQUIRED</prop>  
    124.                 <prop key="remove*">PROPAGATION_REQUIRED</prop>  
    125.                 <prop key="delete*">PROPAGATION_REQUIRED</prop>  
    126.                 <prop key="modify*">PROPAGATION_REQUIRED</prop>  
    127.                 <prop key="*">PROPAGATION_REQUIRED,-java.lang.Exception</prop>  
    128.             </props>  
    129.         </property>  
    130.     </bean>  
    131.       
    132.         <!-- 配置oracle事务 -->  
    133.     <bean id="oracleTransactionManager"  
    134.         class="org.springframework.orm.hibernate4.HibernateTransactionManager">  
    135.         <property name="sessionFactory">  
    136.             <ref local="oracleSessionFactory" />  
    137.         </property>  
    138.     </bean>  
    139.      <!--Mysql hibernate4必须配置为开启事务 否则 getCurrentSession()获取不到-->  
    140.     <bean id="oracleTransactionInterceptor"  
    141.         class="org.springframework.transaction.interceptor.TransactionInterceptor">  
    142.         <property name="transactionManager">  
    143.             <ref local="oracleTransactionManager" />  
    144.         </property>  
    145.         <property name="transactionAttributes">  
    146.             <props>  
    147.                 <prop key="register">PROPAGATION_REQUIRED</prop>  
    148.                 <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>  
    149.                 <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>  
    150.                 <prop key="select*">PROPAGATION_REQUIRED,readOnly</prop>  
    151.                 <prop key="query*">PROPAGATION_REQUIRED,readOnly</prop>  
    152.                 <prop key="sync*">PROPAGATION_REQUIRED</prop>  
    153.                 <prop key="finish*">PROPAGATION_REQUIRED</prop>  
    154.                 <prop key="add*">PROPAGATION_REQUIRED</prop>  
    155.                 <prop key="insert*">PROPAGATION_REQUIRED</prop>  
    156.                 <prop key="edit*">PROPAGATION_REQUIRED</prop>  
    157.                 <prop key="update*">PROPAGATION_REQUIRED</prop>  
    158.                 <prop key="save*">PROPAGATION_REQUIRED</prop>  
    159.                 <prop key="remove*">PROPAGATION_REQUIRED</prop>  
    160.                 <prop key="delete*">PROPAGATION_REQUIRED</prop>  
    161.                 <prop key="modify*">PROPAGATION_REQUIRED</prop>  
    162.                 <prop key="*">PROPAGATION_REQUIRED,-java.lang.Exception</prop>  
    163.             </props>  
    164.         </property>  
    165.     </bean>  
    166.       
    167.     <!-- autoproxy 自动创建代理-->  
    168.       <bean id="ProxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">  
    169.          <property name="beanNames">  
    170.              <list>  
    171.                 <value>*ServiceImpl</value>  
    172.              </list>  
    173.          </property>  
    174.          <property name="interceptorNames">  
    175.              <list>  
    176.                 <value>mysqlTransactionInterceptor</value>  
    177.                 <value>oracleTransactionInterceptor</value>  
    178.              </list>  
    179.          </property>  
    180.       </bean>  
    181.     <!--********************************注入Mysql Dao*********************************************-->  
    182.     <bean id="mysqlBaseDao" class="edu.njupt.zhb.dao.MysqlBaseDao">  
    183.         <property name="sessionFactory" ref="mysqlSessionFactory"></property>  
    184.     </bean>  
    185.     <!--********************************注入Oracle Dao*********************************************-->  
    186.     <bean id="oracleBaseDao" class="edu.njupt.zhb.dao.OracleBaseDao">  
    187.         <property name="sessionFactory" ref="oracleSessionFactory"></property>  
    188.     </bean>  
    189.     <!--********************************注入Services********************************-->  
    190.     <!--********************************注入Action********************************-->  
    191. </beans>  

    优缺点分析:

    优点:我们能够在程序中正常得使用2个不同的Dao,而且可以调用dao的getSessionFactory().getCurrentSession(),使用起来特别的方便。每个Dao都有自己的事务管理,安全性各方面和一个数据库一样。

    缺点:由于事务的配置和自动创建代理的配置,只要有一个数据库连接不了,即便两外一个数据库可以连接,整个项目仍然无法正常启动。对于一些特殊的应用场景,该方案有着很大的缺陷。

    比如某项目的需求为:一个项目需要同时操作2个数据库,如果一个数据库无法连接,那么项目就操作另外一个数据库,同时,将操作的动作记录下来,等另外一个数据库可以连接的时候,再将之前的操作同步到这个数据库中。而且要求,当项目启动的时候,即便只有一个数据库可以连接,那么项目仍然要正常运行。

    方案2

    为了解决上述的需求,我们将其中一个数据库作为本地数据库,另外一个作为远程数据库,当远程数据库无法连接时,我们跳过。整个项目使用本地数据库即可,同时将需要同步的数据,保存起来,待可连接时,再同步。

    [html] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. <?xml version="1.0" encoding="UTF-8"?>  
    2. <beans xmlns="http://www.springframework.org/schema/beans"  
    3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"  
    4.     xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"  
    5.     xsi:schemaLocation="http://www.springframework.org/schema/beans  
    6.     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
    7.     http://www.springframework.org/schema/tx   
    8.     http://www.springframework.org/schema/tx/spring-tx-3.0.xsd  
    9.     http://www.springframework.org/schema/aop  
    10.     http://www.springframework.org/schema/aop/spring-aop-3.0.xsd  
    11.     http://www.springframework.org/schema/context  
    12.     http://www.springframework.org/schema/context/spring-context-3.0.xsd">  
    13.     <!-- 引入datasource配置文件 -->  
    14.     <context:property-placeholder location="classpath:datasource.properties" />  
    15.     <!--创建mysql jdbc数据源 -->  
    16.     <bean id="mysqlDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"  
    17.         destroy-method="close">  
    18.         <property name="driverClass" value="${jdbc.mysql.driver}" />  
    19.         <property name="jdbcUrl" value="${jdbc.mysql.url}" />  
    20.         <property name="user" value="${jdbc.mysql.username}" />  
    21.         <property name="password" value="${jdbc.mysql.password}" />  
    22.         <!-- 指定连接数据库连接池的最小连接数 -->  
    23.         <property name="minPoolSize" value="10" />  
    24.         <!-- 指定连接数据库连接池的最大连接数 -->  
    25.         <property name="maxPoolSize" value="30" />  
    26.         <!-- 指定连接数据库连接池的连接的最大空闲时间 -->  
    27.         <property name="maxIdleTime" value="1800" />  
    28.         <property name="acquireIncrement" value="2" />  
    29.         <property name="maxStatements" value="0" />  
    30.         <!-- 指定连接数据库连接池的初始化连接数 -->  
    31.         <property name="initialPoolSize" value="2" />  
    32.         <property name="idleConnectionTestPeriod" value="1800" />  
    33.         <!-- 当连接失败时,尝试重新连接的次数 -->  
    34.         <property name="acquireRetryAttempts" value="30" />  
    35.         <property name="breakAfterAcquireFailure" value="true" />  
    36.         <property name="testConnectionOnCheckout" value="false" />  
    37.     </bean>  
    38.     <!--创建oracle jdbc数据源 -->  
    39.     <bean id="oracleDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"  
    40.         destroy-method="close">  
    41.         <property name="driverClass" value="${jdbc.oracle.driver}" />  
    42.         <property name="jdbcUrl" value="${jdbc.oracle.url}" />  
    43.         <property name="user" value="${jdbc.oracle.username}" />  
    44.         <property name="password" value="${jdbc.oracle.password}" />  
    45.         <!-- 指定连接数据库连接池的最小连接数 -->  
    46.         <property name="minPoolSize" value="10" />  
    47.         <!-- 指定连接数据库连接池的最大连接数 -->  
    48.         <property name="maxPoolSize" value="30" />  
    49.         <!-- 指定连接数据库连接池的连接的最大空闲时间 -->  
    50.         <property name="maxIdleTime" value="1800" />  
    51.         <property name="acquireIncrement" value="2" />  
    52.         <property name="maxStatements" value="0" />  
    53.         <!-- 指定连接数据库连接池的初始化连接数 -->  
    54.         <property name="initialPoolSize" value="2" />  
    55.         <property name="idleConnectionTestPeriod" value="1800" />  
    56.         <!-- 当连接失败时,尝试重新连接的次数 -->  
    57.         <property name="acquireRetryAttempts" value="1" />  
    58.         <property name="breakAfterAcquireFailure" value="true" />  
    59.         <property name="testConnectionOnCheckout" value="false" />  
    60.     </bean>  
    61.     <!-- 创建MysqlSessionFactory-->  
    62.     <bean id="mysqlSessionFactory"  
    63.         class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">  
    64.         <property name="dataSource" ref="mysqlDataSource" />  
    65.         <property name="hibernateProperties">  
    66.             <props>  
    67.                 <prop key="hibernate.show_sql">true</prop>  
    68.                 <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>  
    69.                 <prop key="current_session_context_class">thread</prop>  
    70.             </props>  
    71.         </property>  
    72.         <property name="mappingResources">  
    73.             <list>  
    74.                 <value>edu/njupt/zhb/model/mysql/Student.hbm.xml</value>  
    75.             </list>  
    76.         </property>  
    77.     </bean>  
    78.   
    79.     <!-- 创建OracleSessionFactory-->  
    80.     <bean id="oracleSessionFactory"  
    81.         class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">  
    82.         <property name="dataSource" ref="oracleDataSource" />  
    83.         <property name="hibernateProperties">  
    84.             <props>  
    85.                 <prop key="hibernate.show_sql">true</prop>  
    86.                 <prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>  
    87.                 <prop key="current_session_context_class">thread</prop>  
    88.             </props>  
    89.         </property>  
    90.         <property name="mappingResources">  
    91.             <list>  
    92.                 <value>edu/njupt/zhb/model/oracle/Student.hbm.xml</value>  
    93.             </list>  
    94.         </property>  
    95.     </bean>  
    96.       
    97.     <!-- 配置Mysql事务 -->  
    98.     <bean id="mysqlTransactionManager"  
    99.         class="org.springframework.orm.hibernate4.HibernateTransactionManager">  
    100.         <property name="sessionFactory">  
    101.             <ref local="mysqlSessionFactory" />  
    102.         </property>  
    103.     </bean>  
    104.      <!--Mysql hibernate4必须配置为开启事务 否则 getCurrentSession()获取不到-->  
    105.     <bean id="mysqlTransactionInterceptor"  
    106.         class="org.springframework.transaction.interceptor.TransactionInterceptor">  
    107.         <property name="transactionManager">  
    108.             <ref local="mysqlTransactionManager" />  
    109.         </property>  
    110.         <property name="transactionAttributes">  
    111.             <props>  
    112.                 <prop key="register">PROPAGATION_REQUIRED</prop>  
    113.                 <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>  
    114.                 <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>  
    115.                 <prop key="select*">PROPAGATION_REQUIRED,readOnly</prop>  
    116.                 <prop key="query*">PROPAGATION_REQUIRED,readOnly</prop>  
    117.                 <prop key="sync*">PROPAGATION_REQUIRED</prop>  
    118.                 <prop key="finish*">PROPAGATION_REQUIRED</prop>  
    119.                 <prop key="add*">PROPAGATION_REQUIRED</prop>  
    120.                 <prop key="insert*">PROPAGATION_REQUIRED</prop>  
    121.                 <prop key="edit*">PROPAGATION_REQUIRED</prop>  
    122.                 <prop key="update*">PROPAGATION_REQUIRED</prop>  
    123.                 <prop key="save*">PROPAGATION_REQUIRED</prop>  
    124.                 <prop key="remove*">PROPAGATION_REQUIRED</prop>  
    125.                 <prop key="delete*">PROPAGATION_REQUIRED</prop>  
    126.                 <prop key="modify*">PROPAGATION_REQUIRED</prop>  
    127.                 <prop key="*">PROPAGATION_REQUIRED,-java.lang.Exception</prop>  
    128.             </props>  
    129.         </property>  
    130.     </bean>  
    131.     <!-- autoproxy 自动创建代理-->  
    132.       <bean id="ProxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">  
    133.          <property name="beanNames">  
    134.              <list>  
    135.                 <value>*ServiceImpl</value>  
    136.              </list>  
    137.          </property>  
    138.          <property name="interceptorNames">  
    139.              <list>  
    140.                 <value>mysqlTransactionInterceptor</value>  
    141.              </list>  
    142.          </property>  
    143.       </bean>  
    144.     <!--********************************注入Mysql Dao*********************************************-->  
    145.     <bean id="mysqlBaseDao" class="edu.njupt.zhb.dao.MysqlBaseDao">  
    146.         <property name="sessionFactory" ref="mysqlSessionFactory"></property>  
    147.     </bean>  
    148.     <!--********************************注入Oracle Dao*********************************************-->  
    149.     <bean id="oracleBaseDao" class="edu.njupt.zhb.dao.OracleBaseDao">  
    150.         <property name="sessionFactory" ref="oracleSessionFactory"></property>  
    151.     </bean>  
    152.     <!--********************************注入Services********************************-->  
    153.     <!--********************************注入Action********************************-->  
    154. </beans>  

    这种配置下,oracleBaseDao的数据源的属性:acquireRetryAttempts的值配置为1,即便无法连接,我们也只需要连接一次,不会出现“卡住”的情况。而且,由于oracleBaseDao中,我们没有配置事务,因此,dao无法获得getCurrentSession,只能通过sessionFactory().openSession()来使用Hibernate。同时为了捕获异常,我们将session设置成手动提交的方式。
  • 相关阅读:
    作业3
    数组求和
    2.自己的Github试用过程
    2.自己的Github注册流程
    图片左右滑动整理为插件
    artDialog中的time参数,ajax请求中的异步与同步
    简单的图片放大镜效果插件
    3月份学习安排
    前端好的网站
    web app开发中遇到的问题
  • 原文地址:https://www.cnblogs.com/u0mo5/p/4168491.html
Copyright © 2020-2023  润新知