1.1.1 实现环境
l JBoss-4.2.3.GA
l MySQL5.0(win环境)
l mysql-connector-java-5.1-nightly-20100613-bin.jar
l Spring2.5
l Hibernate3.2
l MyEclipse8.5
1.1.1.1 JBoss AS4 的配置
l 每一个数据库都对应于一个数据源
l 每个数据源都绑定到容器的JNDI树
下图是XA Datasource的XMLSchema描述
1、其中Datasource class需要使用
<xa-datasource-class>
com.mysql.jdbc.jdbc2.optional.MysqlXADataSource
</xa-datasource-class>
2、<use-java-context>false</use-java-context> 表示JNDI名称是否需要java:
3、每一个数据源在jboss-4.2.3.GA/server/default/deploy 都对应一个 *-ds.xml
4、具体内容如下(连接数目等省略内容,需要根据实际环境性能需求来设定,该处均默认)
mysql-test-ds.xml
<datasources>
<xa-datasource>
<jndi-name>MySqlDS</jndi-name>
<xa-datasource-class>
com.mysql.jdbc.jdbc2.optional.MysqlXADataSource
</xa-datasource-class>
<xa-datasource-property name="URL">
jdbc:mysql://localhost:3306/test
</xa-datasource-property>
<user-name>root</user-name>
<password>root</password>
<use-java-context>false</use-java-context>
<track-connection-by-tx>true</track-connection-by-tx>
<exception-sorter-class-name>
org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter
</exception-sorter-class-name>
<metadata>
<type-mapping>mySQL</type-mapping>
</metadata>
</xa-datasource>
</datasources>
mysql-test1-ds.xml
<datasources>
<xa-datasource>
<jndi-name>MySqlDS1</jndi-name>
<xa-datasource-class>
com.mysql.jdbc.jdbc2.optional.MysqlXADataSource
</xa-datasource-class>
<xa-datasource-property name="URL">
jdbc:mysql://localhost:3306/test1
</xa-datasource-property>
<user-name>root</user-name>
<password>root</password>
<use-java-context>false</use-java-context>
<track-connection-by-tx>true</track-connection-by-tx>
<exception-sorter-class-name>
org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter
</exception-sorter-class-name>
<metadata>
<type-mapping>mySQL</type-mapping>
</metadata>
</xa-datasource>
</datasources>
5、部署的时候如果有jar包冲突就删除冲突的jar包,比如jta.jar、asm2.2.3.jar
1.1.1.2 Spring的配置
1、 JNDI取得数据源
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="MySqlDS" />
<property name="lookupOnStartup" value="true" />
</bean>
2、 事务使用
<bean id="transactionManager-xa"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManagerName" value="java:/TransactionManager" />
</bean>
3、 定义多个sessionFactory 对应每个数据源
4、 需要多数据库访问的service
<util:map id="multipleDSDao">
<entry key="simpleDao" value-ref="simpleDao" />
<entry key="newSimpleDao" value-ref="newSimpleDao" />
</util:map>
<bean id="simpleService" class="service.SimpleService">
<property name="daoMap">
<ref bean="multipleDSDao" />
</property>
</bean>
1.1.1.3 数据库
数据库可以位于不同的物理机,为了试验方便,在本机建立测试环境
create database test;
use test;
create table T_ClusterGroup
(
CGID bigint auto_increment not null,
CGNAME varchar(200) not null,
primary key (CGID)
);
create database test1;
use test1
create table T_ClusterGroup
(
CGID bigint auto_increment not null,
CGNAME varchar(200) not null,
primary key (CGID)
);
1.1.1.4 部署过程
l 下载带有XA功能的JDBC mysql-connector-java-5.1-nightly-20100613-bin.jar
l JDBC放入jboss的lib中
l 配置好两个数据源 mysql-test1-ds.xml mysql-test-ds.xml放入deploy中
l 启动JBoss查看定义的数据源是否绑定到JNDI上
l Spring配置多个数据源
l Spring的事务配置注意:默认对于CheckException是不回滚事务的、Hibernate必须有默认的sessionFactory
l service中抛出一个Exception,测试事务是否回滚
l 查看JBoss中的web部署,如果lib下有jta.jar、asm2.2.3.jar 都删除,否则冲突异常
l MySQL对JTA的支持程度参见文档
刷新index.jsp,会调用数据库操作,观测两个数据库内容。具体逻辑,参见源代码
1.1.2 验证
在Service的业务方法saveCGToAll()中向多个数据库保存信息
为了测试方便,测试入口在index.jsp 调用 test.SimpleTest.test1();
第一次, 业务方法不抛异常,Spring配置事务
记录插入了TEST和TEST1两个数据库
第二次, 业务方法抛出异常,Spring不配置JTA事务
一个记录插入TEST数据,一个记录没有插入TEST1数据,数据不一致
第三次, 业务方法抛出异常,Spring配置事务
两个数据库均没有插入数据,数据一致
验证结果:多数据源分布式事务配置成功
1.1.3 其他参考
XAConnection doesn't allow second XA START
http://bugs.mysql.com/bug.php?id=17343
Description:
XAConnection doesn't allow second XA START-XA END pair to be executed in the same transaction over the same XAConnection.
XAER_INVAL: Invalid arguments