解决跨库数据一致性问题通常会采用jta/xa的事务方式,下面介绍一下利用atomikos在spring3.x+hibernate3.x下的配置方式:
一、事务能解决的问题
保持ACID,也就是原子性 ( Atomicity )、一致性 ( Consistency )、隔离性 ( Isolation ) 和持久性 ( Durabilily ),分布式环境下,或者说假如有多个数据库,如果保持acid呢?
二、分布式事务
分布式事务(Distributed Transaction)包括:
- 事务管理器(Transaction Manager),事务管理器承担着所有事务参与单元的协调与控制;
- 一个或多个支持 XA 协议的资源管理器 ( Resource Manager ),我们可以将资源管理器看做任意类型的持久化数据存储。
与本地事务相比,XA 协议的系统开销大,在系统开发过程中应慎重考虑是否确实需要分布式事务。
三、atomikos+spring+hibernate配置jta事务
- 配置多个xa数据源
<bean id="dataSourceSrc1" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close"> <property name="uniqueResourceName" value="mysql/master"/> <!-- 使用Mysql XADataSource(mysql>=5.0, Connector/J>=5.0才可以支持XADatasource)--> <property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"/> <property name="xaProperties"> <props> <prop key="URL">${db.jdbcUrl}</prop> <prop key="user">${db.user}</prop> <prop key="password">${db.password}</prop> </props> </property> <property name="poolSize" value="${db.initialPoolSize}" /> <property name="minPoolSize" value="${db.minPoolSize}" /> <property name="maxPoolSize" value="${db.maxPoolSize}" /> </bean>
<bean id="dataSourceSrc2" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close"> <property name="uniqueResourceName" value="mysql/slaver"/> <!-- 使用Mysql XADataSource(mysql>=5.0, Connector/J>=5.0才可以支持XADatasource)--> <property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"/> <property name="xaProperties"> <props> <prop key="URL">${db.cms.jdbcUrl}</prop> <prop key="user">${db.user}</prop> <prop key="password">${db.password}</prop> </props> </property> <property name="poolSize" value="${db.initialPoolSize}" /> <property name="minPoolSize" value="${db.minPoolSize}" /> <property name="maxPoolSize" value="${db.maxPoolSize}" /> </bean>
- 配置每个数据源对应的hibernate的sessionFactory,这里不举例了
- 配置spring的atomikos事务
<tx:annotation-driven proxy-target-class="true"/> <bean id="jtaTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"> <qualifier value="jta"/> <property name="transactionManager" ref="atomikosTransactionManager"/> <property name="userTransaction" ref="atomikosUserTransaction"/> </bean> <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="3000"/> </bean>
其中的qualifier表示事务管理器的唯一标识,可以配置多个事务管理器,通过使用注解来区分该方法用哪个事务管理器处理。如@Transactional("jta")
四、spring的xa数据源代理
据说以下配置可以提高xa数据源的效率,没有验证
<bean id="dataSource1" class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy"> <constructor-arg ref="dataSourceSrc1"/> </bean>