最近公司对中心数据库进行了拆分,分解成了很多子库,然后再对子库进行水平分割,那么很麻烦的一个事情就是如何保证多数据源事务的完整性.
在网上找到了点资料,现已完成事务处理方面的需求,把过程总结一下:
1、首先从官网下载atomikos与jotm的开源项目
2、导入如下包至工程中
alib/jca.jar
alib/jms.jar
alib/jmx.jar
alib/jta.jar
alib/slf4j-api-1.4.3.jar
alib/slf4j-nop-1.4.3.jar
atomikos/atomikos-util.jar
atomikos/transactions.jar
atomikos/transactions-api.jar
atomikos/transactions-essentials-all.jar
atomikos/transactions-hibernate2.jar
atomikos/transactions-hibernate3.jar
atomikos/transactions-jdbc.jar
atomikos/transactions-jdbc-deprecated.jar
atomikos/transactions-jms.jar
atomikos/transactions-jms-deprecated.jar
atomikos/transactions-jta.jar
ibatis/ibatis-2.3.4.726.jar
jakarta-commons/commons-beanutils.jar
jakarta-commons/commons-codec-1.3.jar
jakarta-commons/commons-collections.jar
jakarta-commons/commons-dbcp.jar
jakarta-commons/commons-digester.jar
jakarta-commons/commons-discovery-0.2.jar
jakarta-commons/commons-fileupload-1.2.jar
jakarta-commons/commons-httpclient-3.0.jar
jakarta-commons/commons-io-1.3.1.jar
jakarta-commons/commons-lang.jar
jakarta-commons/commons-logging.jar
jakarta-commons/commons-logging-1.1.1.jar
jakarta-commons/commons-net-2.0.jar
jakarta-commons/commons-pool.jar
jakarta-commons/commons-validator.jar
jakarta-commons/log4j-1.2.14.jar
jdbc/mysql/mysql-connector-java-5.1.7-bin.jar
jotm/jotm-client.jar
jotm/jotm-core.jar
jotm/jotm-datasource.jar
jotm/jotm-jms.jar
jotm/jotm-standalone.jar
jotm/ow2-connector-1.5-spec.jar
jotm/ow2-jta-1.1-spec.jar
jotm/xapool.jar
junit/junit-4.4.jar
log4j/log4j-1.2.14.jar
objectweb/asm-all-3.1.jar
objectweb/cglib-nodep-2.1_3.jar
quartz/quartz-all-1.6.0-alpha.jar
spring/aopalliance-1.0.jar
spring/aspectjweaver.jar
spring/spring.jar
spring/spring-aspects.jar
spring/spring-mock.jar
common/activation.jar
jakarta-commons/jakarta-oro-2.0.8.jar
3、在classpath下添加jta.properties文件
#JTAtransction
com.atomikos.icatch.service=com.atomikos.icatch.standalone.UserTransactionServiceFactory
com.atomikos.icatch.console_file_name=tm.release.out
com.atomikos.icatch.log_base_name=tm.releaselog
com.atomikos.icatch.tm_unique_name=com.atomikos.spring.jdbc.tm.release
com.atomikos.icatch.console_log_level=INFO
4、分别配置相关的数据源
(一)、配置Spring properties文件
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>/WEB-INF/classes/db-mailtask.properties</value>
</list>
</property>
</bean>
(二)应用主库数据源
<bean id="dataSource-unimail" class="com.atomikos.jdbc.SimpleDataSourceBean" init-method="init" destroy-method="close">
<property name="uniqueResourceName">
<value>${datasource.uniqueResourceName}</value>
</property>
<property name="xaDataSourceClassName">
<value>${database.driver_class}</value>
</property>
<property name="xaDataSourceProperties">
<value>URL=${database.url};user=${database.username};password=${database.password}</value>
</property>
<property name="exclusiveConnectionMode">
<value>${connection.exclusive.mode}</value>
</property>
<property name="connectionPoolSize">
<value>${connection.pool.size}</value>
</property>
<property name="connectionTimeout">
<value>${connection.timeout}</value>
</property>
<property name="validatingQuery">
<value>SELECT 1</value>
</property>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="namingStrategy">
<ref bean="namingStrategy" />
</property>
<property name="mappingResources">
<list>
<value>
XXXX.hbm.xml
</value>
</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.hbm2ddl.auto">
${hibernate.hbm2ddl.auto}
</prop>
</property>
<property name="dataSource">
<ref bean="dataSource-unimail" />
</property>
</bean>
<bean id="CompanyChargeDetailDAO"
class="cn.unisoftware.unimail.dao.hibernate.CompanyChargeDetailDAO">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
(三)配置从库数据源
<bean id="mail-dataSource" class="com.atomikos.jdbc.SimpleDataSourceBean" init-method="init" destroy-method="close">
<property name="uniqueResourceName">
<value>${mail.datasource.uniqueResourceName}</value>
</property>
<property name="xaDataSourceClassName">
<value>${mail.database.driver_class}</value>
</property>
<property name="xaDataSourceProperties">
<value>URL=${mail.database.url};user=${mail.database.username};password=${mail.database.password}</value>
</property>
<property name="exclusiveConnectionMode">
<value>${mail.connection.exclusive.mode}</value>
</property>
<property name="connectionPoolSize">
<value>${mail.connection.pool.size}</value>
</property>
<property name="connectionTimeout">
<value>${connection.timeout}</value>
</property>
<property name="validatingQuery">
<value>SELECT 1</value>
</property>
</bean>
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation"><value>classpath:task-sqlMapConfig.xml</value></property>
<property name="dataSource" ref="mail-dataSource" />
</bean>
<bean id="mdaMessageInfoDAO" class="cn.unisoftware.unimail.mda.persistence.sqlmapdao.task.MdaMessageInfoSqlMapDao">
<property name="sqlMapClient" ref="sqlMapClient"/>
</bean>
(四) 事务处理部份
<!-- ========================= ASPECT CONFIGURATION ======================== -->
<bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"
init-method="init" destroy-method="close">
<property name="forceShutdown" value="true"/>
</bean>
<bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">
<property name="transactionTimeout" value="${transaction.timeout}"/>
</bean>
<!-- JTA事务管理器 -->
<bean id="springTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager" ref="atomikosTransactionManager"/>
<property name="userTransaction" ref="atomikosUserTransaction"/>
</bean>
<!-- 事务切面配置 -->
<aop:config>
<aop:pointcut id="serviceOperation" expression="execution(* *..service*..*(..))"/>
<aop:advisor pointcut-ref="serviceOperation" advice-ref="txAdvice"/>
</aop:config>
<!-- 通知配置 -->
<tx:advice id="txAdvice" transaction-manager="springTransactionManager">
<tx:attributes>
<tx:method name="*" rollback-for="Exception"/>
</tx:attributes>
</tx:advice>