开发中,项目肯定会遇到连接多个数据库,这就是多数据源,有了多数据源就要有多个事务管理,这就引出了分布式事务管理,接下来看代码。项目架构 springMVC+spring+ibatis用maven管理
1. 多个数据源配置文件
#由于我的两个数据库都是一个连接所以用户名密码都是一样的
connect.username=root
connect.password=root
connect.url=jdbc:mysql://127.0.0.1:3306/xiaomianaodb?useUnicode=true&autoReconnect=true&failOverReadOnly=false&characterEncoding=UTF-8
connect.url.adapter=jdbc:mysql://127.0.0.1:3306/adapter?useUnicode=true&autoReconnect=true&failOverReadOnly=false&characterEncoding=UTF-8
connect.driverClassName=com.mysql.jdbc.Driver
connect.minPoolSize = 1
connect.maxPoolSize = 50
connect.initialPoolSize = 1
connect.maxIdleTime = 25000
connect.acquireIncrement = 1
connect.acquireRetryAttempts = 30
connect.acquireRetryDelay = 1000
connect.testConnectionOnCheckin = true
connect.automaticTestTable = t_c3p0
connect.idleConnectionTestPeriod = 18000
connect.checkoutTimeout=5000
2. applicationContext.xml 配置文件
数据源1配置如下
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass">
<value>${connect.driverClassName}</value>
</property>
<property name="jdbcUrl">
<value>${connect.url}</value>
</property>
<property name="user">
<value>${connect.username}</value>
</property>
<property name="password">
<value>${connect.password}</value>
</property>
<property name="minPoolSize">
<value>${connect.minPoolSize}</value>
</property>
<property name="maxPoolSize">
<value>${connect.maxPoolSize}</value>
</property>
<property name="initialPoolSize">
<value>${connect.initialPoolSize}</value>
</property>
<property name="maxIdleTime">
<value>${connect.maxIdleTime}</value>
</property>
<property name="acquireIncrement">
<value>${connect.acquireIncrement}</value>
</property>
<property name="acquireRetryAttempts">
<value>${connect.acquireRetryAttempts}</value>
</property>
<property name="acquireRetryDelay">
<value>${connect.acquireRetryDelay}</value>
</property>
<property name="testConnectionOnCheckin">
<value>${connect.testConnectionOnCheckin}</value>
</property>
<property name="automaticTestTable">
<value>${connect.automaticTestTable}</value>
</property>
<property name="idleConnectionTestPeriod">
<value>${connect.idleConnectionTestPeriod}</value>
</property>
<property name="checkoutTimeout">
<value>${connect.checkoutTimeout}</value>
</property>
</bean>
<bean id="sqlMap" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation">
<value>classpath:spring/sqlMap-Config.xml</value>
</property>
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientTemplate">
<property name="sqlMapClient" ref="sqlMap" />
</bean>
数据源2配置
<bean id="dataSourceAdapter" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass">
<value>${connect.driverClassName}</value>
</property>
<property name="jdbcUrl">
<value>${connect.url.adapter}</value>
</property>
<property name="user">
<value>${connect.username}</value>
</property>
<property name="password">
<value>${connect.password}</value>
</property>
<property name="minPoolSize">
<value>${connect.minPoolSize}</value>
</property>
<property name="maxPoolSize">
<value>${connect.maxPoolSize}</value>
</property>
<property name="initialPoolSize">
<value>${connect.initialPoolSize}</value>
</property>
<property name="maxIdleTime">
<value>${connect.maxIdleTime}</value>
</property>
<property name="acquireIncrement">
<value>${connect.acquireIncrement}</value>
</property>
<property name="acquireRetryAttempts">
<value>${connect.acquireRetryAttempts}</value>
</property>
<property name="acquireRetryDelay">
<value>${connect.acquireRetryDelay}</value>
</property>
<property name="testConnectionOnCheckin">
<value>${connect.testConnectionOnCheckin}</value>
</property>
<property name="automaticTestTable">
<value>${connect.automaticTestTable}</value>
</property>
<property name="idleConnectionTestPeriod">
<value>${connect.idleConnectionTestPeriod}</value>
</property>
<property name="checkoutTimeout">
<value>${connect.checkoutTimeout}</value>
</property>
</bean>
<bean id="sqlMapAdapter" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation">
<value>classpath:spring/sqlMap-Config-Adapter.xml</value>
</property>
<property name="dataSource" ref="dataSourceAdapter" />
</bean>
<bean id="sqlMapClientAdapter" class="org.springframework.orm.ibatis.SqlMapClientTemplate">
<property name="sqlMapClient" ref="sqlMapAdapter" />
</bean>
数据源1的事务管理如下
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED" />
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="create*" propagation="REQUIRED" />
<tx:method name="insert*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="merge*" propagation="REQUIRED" />
<tx:method name="del*" propagation="REQUIRED" />
<tx:method name="remove*" propagation="REQUIRED" />
<tx:method name="put*" read-only="true" />
<tx:method name="query*" read-only="true" />
<tx:method name="use*" read-only="true" />
<tx:method name="get*" read-only="true" />
<tx:method name="count*" read-only="true" />
<tx:method name="find*" read-only="true" />
<tx:method name="list*" read-only="true" />
<tx:method name="*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>
<aop:config expose-proxy="true">
<aop:pointcut id="txPointcut" expression="execution(* com.*.*.service.*Service.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut" />
</aop:config>
数据源2的事务管理
<!-- 配置事务管理器 -->
<bean id="transactionManagerAdapter"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSourceAdapter"></property>
</bean>
<tx:advice id="txAdviceAdapter" transaction-manager="transactionManagerAdapter">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED" />
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="create*" propagation="REQUIRED" />
<tx:method name="insert*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="merge*" propagation="REQUIRED" />
<tx:method name="del*" propagation="REQUIRED" />
<tx:method name="remove*" propagation="REQUIRED" />
<tx:method name="put*" read-only="true" />
<tx:method name="query*" read-only="true" />
<tx:method name="use*" read-only="true" />
<tx:method name="get*" read-only="true" />
<tx:method name="count*" read-only="true" />
<tx:method name="find*" read-only="true" />
<tx:method name="list*" read-only="true" />
<tx:method name="*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>
<aop:config expose-proxy="true">
<aop:pointcut id="txPointcutAdapter" expression="execution(* com.*.*.service.*Service.*(..))"/>
<aop:advisor advice-ref="txAdviceAdapter" pointcut-ref="txPointcutAdapter" />
</aop:config>
3. 创建两个sqlMap-Config.xml配置文件如下
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMapConfig PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN"
"http://www.ibatis.com/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
<!--<sqlMap>元素用于包括SQL Map映射文件和其他的SQL Map配置文件。-->
<settings lazyLoadingEnabled="true" useStatementNamespaces="true" />
<!-- 系统配置 开始 -->
<sqlMap resource="com/hmsg/appReleaseRecord/sql/AppReleaseRecord.xml" /> <!-- 用户 -->
</sqlMapConfig>
4. dao层引入sqlMapClient
//数据源1 注入
@Autowired() @Qualifier("sqlMapClient")
private SqlMapClientTemplate sqlMapClient;
//数据源2 注入
@Autowired() @Qualifier("sqlMapClientAdapter")
private SqlMapClientTemplate sqlMapClient;
到此就结束了。启动项目可以试试了