SSH 多数据源连接

最近做两个项目的合并 类似的功能以及数据库 但是有表关系这块两个相差比较多 这样也会造成项目要修改大量的逻辑部分 容易引起更多BUG出现 本人也是为了偷懒 决定以A为主项目 进行操作

下面大概说下

A项目有aa数据库  B项目有一个bb数据库

功能:

      由A项目操作B项目数据库(bb)  同时数据B 添加触发器 对A项目的aa数据库进行一些数据同步

第一步

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
	<!-- =================================================================== -->
	<!-- init.properties                                                     -->
	<!-- =================================================================== -->
	<bean id="placeholderConfig"
		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="location">
			<value>classpath:../../config/init.properties</value>
		</property>
	</bean>

	
	<!-- =================================================================== -->
	<!-- c3p0 dataSource                                                     -->
	<!-- =================================================================== -->

       <!-- 数据源1-->
	<bean id="dataSource"
		class="com.mchange.v2.c3p0.ComboPooledDataSource"
		destroy-method="close">
		<property name="driverClass">
			<value>${datasource.driver}</value>
		</property>
		<property name="jdbcUrl">
			<value>${datasource.url}</value>
		</property>
		
		<property name="user">
			<value>${datasource.username}</value>
		</property>
		<property name="password">
			<value>${datasource.password}</value>
		</property>

		<!--连接池中保留的最小连接数。-->
		<property name="minPoolSize">
			<value>10</value>
		</property>

		<!--连接池中保留的最大连接数。Default: 1500 -->
		<property name="maxPoolSize">
			<value>1000</value>
		</property>

		<!--初始化时获取的连接数,取值应在minPoolSize与maxPoolSize之间。Default: 20 -->
		<property name="initialPoolSize">
			<value>20</value>
		</property>

		<!--最大空闲时间,10秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
		<property name="maxIdleTime">
			<value>10</value>
		</property>

		<!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 10 -->
		<property name="acquireIncrement">
			<value>10</value>
		</property>

		<!--JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量。但由于预缓存的statements
			属于单个connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素。
			如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default: 0-->
		<property name="maxStatements">
			<value>0</value>
		</property>
		<property name="maxStatementsPerConnection">
			<value>0</value>
		</property>

		<!--每5小时检查所有连接池中的空闲连接。Default: 0 -->
		<property name="idleConnectionTestPeriod">
			<value>18000</value>
		</property>

		<!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 -->
		<property name="acquireRetryAttempts">
			<value>30</value>
		</property>

		<!--获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。但是数据源仍有效
			保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试
			获取连接失败后该数据源将申明已断开并永久关闭。Default: false-->
		<property name="breakAfterAcquireFailure">
			<value>false</value>
		</property>

		<!--因性能消耗大请只在需要的时候使用它。如果设为true那么在每个connection提交的
			时候都将校验其有效性。建议使用idleConnectionTestPeriod或automaticTestTable
			等方法来提升连接测试的性能。Default: false -->
		<property name="testConnectionOnCheckout">
			<value>false</value>
		</property>
		
		<!--获取connnection时测试是否有效 -->
		<property name="testConnectionOnCheckin">
			<value>true</value>
		</property>
		
		<!--测试数据库连接的表名 -->
		<property name="automaticTestTable">
			<value>C3P0TestTable</value>
		</property>
		
		<!--定义所有连接测试都执行的测试语句。在使用连接测试的情况下这个一显著提高测试速度。
		  	注意:测试的表必须在初始数据源的时候就存在。Default: null-->    
		<property name="preferredTestQuery">
		    <value>select * from C3P0TestTable</value>
		</property>
	</bean>

        
        <!-- 数据源2-->
	<bean id="zfdataSource"
		class="com.mchange.v2.c3p0.ComboPooledDataSource"
		destroy-method="close">
		<property name="driverClass">
			<value>${datasource.driver}</value>
		</property>
		<property name="jdbcUrl">
			<value>${zf.datasource.url}</value>
		</property>
		
		<property name="user">
			<value>${zf.datasource.username}</value>
		</property>
		<property name="password">
			<value>${zf.datasource.password}</value>
		</property>

		<!--连接池中保留的最小连接数。-->
		<property name="minPoolSize">
			<value>10</value>
		</property>

		<!--连接池中保留的最大连接数。Default: 1500 -->
		<property name="maxPoolSize">
			<value>1000</value>
		</property>

		<!--初始化时获取的连接数,取值应在minPoolSize与maxPoolSize之间。Default: 20 -->
		<property name="initialPoolSize">
			<value>20</value>
		</property>

		<!--最大空闲时间,10秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
		<property name="maxIdleTime">
			<value>10</value>
		</property>

		<!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 10 -->
		<property name="acquireIncrement">
			<value>10</value>
		</property>

		<!--JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量。但由于预缓存的statements
			属于单个connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素。
			如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default: 0-->
		<property name="maxStatements">
			<value>0</value>
		</property>
		<property name="maxStatementsPerConnection">
			<value>0</value>
		</property>

		<!--每5小时检查所有连接池中的空闲连接。Default: 0 -->
		<property name="idleConnectionTestPeriod">
			<value>18000</value>
		</property>

		<!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 -->
		<property name="acquireRetryAttempts">
			<value>30</value>
		</property>

		<!--获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。但是数据源仍有效
			保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试
			获取连接失败后该数据源将申明已断开并永久关闭。Default: false-->
		<property name="breakAfterAcquireFailure">
			<value>false</value>
		</property>

		<!--因性能消耗大请只在需要的时候使用它。如果设为true那么在每个connection提交的
			时候都将校验其有效性。建议使用idleConnectionTestPeriod或automaticTestTable
			等方法来提升连接测试的性能。Default: false -->
		<property name="testConnectionOnCheckout">
			<value>false</value>
		</property>
		
		<!--获取connnection时测试是否有效 -->
		<property name="testConnectionOnCheckin">
			<value>true</value>
		</property>
		
		<!--测试数据库连接的表名 -->
		<property name="automaticTestTable">
			<value>C3P0TestTable</value>
		</property>
		
		<!--定义所有连接测试都执行的测试语句。在使用连接测试的情况下这个一显著提高测试速度。
		  	注意:测试的表必须在初始数据源的时候就存在。Default: null-->    
		<property name="preferredTestQuery">
		    <value>select * from C3P0TestTable</value>
		</property>
	</bean>
	
	
	<!-- =================================================================== -->
	<!-- Hibernate sessionFactory                                            -->
	<!-- =================================================================== -->
       
       <!-- session 1 -->
	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
		destroy-method="destroy">
		<property name="dataSource">
			<ref local="dataSource" />
		</property>
		<property name="mappingResources">
			<list>
				<value>test/a/A.hbm.xml</valu
			</list>
		</property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">${hibernate.dialect}</prop>
				<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
				
				<prop key="hibernate.jdbc.fetch_size">${hibernate.jdbc.fetch_size}</prop>
				<prop key="hibernate.jdbc.batch_size">${hibernate.jdbc.batch_size}</prop>
				<prop key="hibernate.generate_statistics">${hibernate.generate_statistics}</prop>
				<prop key="hibernate.connection.release_mode">${hibernate.connection.release_mode}</prop>
				<prop key="hibernate.autoReconnect">${hibernate.autoReconnect}</prop>
                <prop key="hibernate.cglib.use_reflection_optimizer">${hibernate.cglib.use_reflection_optimizer}</prop>
                
				<prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop>
				<prop key="hibernate.cache.use_second_level_cache">${hibernate.cache.use_second_level_cache}</prop> 
				<prop key="hibernate.cache.provider_class">${hibernate.cache.provider_class}</prop>
			</props>
			
		</property>
	</bean>
	
        
        <!-- session 2 -->




<bean id="zfsessionFactory"class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"><property name="dataSource"><ref local="zfdataSource" /></property><property name="mappingResources"><list> <value>test/b/B.hbm.xml</value></list></property><property
 name="hibernateProperties"><props><prop key="hibernate.show_sql">${hibernate.show_sql}</prop></props></property></bean><!-- =================================================================== --><!-- transactionManager --><!-- ===================================================================
 --> <!-- 事务 1--><bean id="transactionManager"class="org.springframework.orm.hibernate3.HibernateTransactionManager"><property name="sessionFactory"><ref local="sessionFactory" /></property></bean>
       <!-- 事务 2-->
	<bean id="zftransactionManager"
		class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory">
			<ref local="zfsessionFactory" />
		</property>
	</bean>
	
	<bean id="hibernateTemplate" 
        class="org.springframework.orm.hibernate3.HibernateTemplate">
      	<property name="sessionFactory"><ref bean="sessionFactory"/></property>
    	<property name="cacheQueries" value="${hibernate.cache.use_query_cache}"></property>
	</bean>

	<!-- =================================================================== -->
	<!-- txProxyTemplate                                                     -->
	<!-- =================================================================== -->
	
	<bean id="transactionBase" 
            class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" 
            lazy-init="true" abstract="true"> 
        <!-- 配置事务管理器 --> 
        <property name="transactionManager" ref="zftransactionManager" /> 
        <!-- 配置事务属性 --> 
        <property name="transactionAttributes"> 
            <props> 
                <prop key="*">PROPAGATION_REQUIRED</prop> 
            </props> 
        </property> 
    </bean>
    
	<bean id="txProxyTemplate" abstract="true"
		class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
		<property name="transactionManager">
			<ref bean="transactionManager" />
		</property>
		<property name="transactionAttributes">
			<props>
				<!-- 
					<prop key="Create*">PROPAGATION_REQUIRED,-Exception</prop>
					<prop key="delete*">PROPAGATION_REQUIRED,-Exception</prop>
					<prop key="Remove*">PROPAGATION_REQUIRED,-Exception</prop>
					<prop key="update*">PROPAGATION_REQUIRED,-Exception</prop>
					<prop key="validate*">PROPAGATION_REQUIRED,-Exception</prop>
					<prop key="Invite*">PROPAGATION_REQUIRED,-Exception</prop>
					<prop key="Log*">PROPAGATION_REQUIRED,-Exception</prop>
					<prop key="Modify*">PROPAGATION_REQUIRED,-Exception</prop>
					<prop key="permission*">PROPAGATION_REQUIRED,-Exception</prop>
					<prop key="Initialize*">PROPAGATION_REQUIRED,-Exception</prop>
				-->
				<prop key="*">PROPAGATION_REQUIRED,-Exception</prop>
				<prop key="save*">PROPAGATION_REQUIRES_NEW,-Exception</prop>
			</props>
		</property>
	</bean>
</beans>



然后是要配置dao的注入

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
	
	<bean id="tblorganizationDAO" class="com.avonaco.dao.TblOrganizationDAO">
		<property name="sessionFactory">
			<ref bean="zfsessionFactory" />
		</property>
	</bean>
	  <!-- 数据源 1 session-->
         <bean id="A" class="test.a.A">
		<property name="sessionFactory">
			<ref bean="sessionFactory" />
		</property>
	</bean>
 <!-- 数据源 2 session-->
	<bean id="B" class="test.a.B">
		<property name="sessionFactory">
			<ref bean="zfsessionFactory" />
		</property>
	</bean>
</beans>


然后代码里去调用就可以了

  这一有一点一定要注意.. 就是事务

当你在A项目中对B数据库进行了CUD操作 此时你在A数据库是可以查看到触发器同步过来的数据  但是你在A项目去获取aa数据库的数据 发现并没有改变

这是因为事务的关系 因为hibernate的事务 和 触发器的事务不是通过一个事务 我理解的原因是 当你修改了bb数据库 此时hibernate缓存中会更新bb数据库的数据 当时不会同步更新缓存中aa数据库的数据

因为在项目中用到了hibernate的乐观锁机制 发现在A项目只有你指定条件去查询这条数据数据的时候 乐观锁检查版本是否改变 从而进行更新

UPDATE A SET VERSION=?, name=? WHERE id=? AND VERSION=?

此时你在页面操作A项目去修改bb数据库 页面上总是显示成功 但是你绝看不到页面上有任何数据进行了变化 而你数据库查看发现其实aa数据已经被同步过来了..

这就是因为事务不同步造成的

因为只是一些小模块的合并 所以暂时没有考虑是使用JTA事务 目前我的的做法是 当在A项目操作完bb数据库后 同时在根据操作条件查询一下aa数据库 从而达到他们的事务一致性  只是这样增加了数据库连接 如果在大量数据的时候 此方法肯定是不可行的..





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值