(个人观点)
在一个事务中包含多个数据源的更新操作时,需要JTA的支持,通常JTA的支持是由J2EE容器提供的(WAS,Weblogic...),也有单独实现JTA的第3方jar。
Spring提供的是jotm和xapool,但在配置过程中遇到了问题,使用org.enhydra.jdbc.standard.StandardXADataSource做数据源时,它的shutdown方法是带参数的
<bean id="innerMysqlDataSource" class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown">
...
</bean>
xapool的文档做的不好就没有继续,又找了另一个,AtomikosTransactionsEssentials(支持JMS和JDBC作为数据源)。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<tx:annotation-driven />
<bean id="DS1" class="com.atomikos.jdbc.AtomikosDataSourceBean"
init-method="init" destroy-method="close">
<property name="uniqueResourceName">
<value>DB1</value>
</property>
<property name="xaDataSourceClassName">
<value>com.ibm.db2.jcc.DB2XADataSource</value>
</property>
<property name="xaProperties">
<props>
<prop key="serverName">XXX</prop>
<prop key="portNumber">50000</prop>
<prop key="databaseName">DB1</prop>
<prop key="driverType">4</prop>
<prop key="user">XXX</prop>
<prop key="password">XXX</prop>
</props>
</property>
<property name="maxIdleTime" value="XXX" />
<property name="maxPoolSize" value="XXX" />
<property name="minPoolSize" value="XXX" />
</bean>
<bean id="DS2" class="com.atomikos.jdbc.AtomikosDataSourceBean"
init-method="init" destroy-method="close">
<property name="uniqueResourceName">
<value>DB2</value>
</property>
<property name="xaDataSourceClassName">
<value>com.ibm.db2.jcc.DB2XADataSource</value>
</property>
<property name="xaProperties">
<props>
<prop key="serverName">XXX</prop>
<prop key="portNumber">50000</prop>
<prop key="databaseName">DB2</prop>
<prop key="driverType">4</prop>
<prop key="user">XXX</prop>
<prop key="password">XXX</prop>
</props>
</property>
<property name="maxIdleTime" value="XXX" />
<property name="maxPoolSize" value="XXX" />
<property name="minPoolSize" value="XXX" />
</bean>
<!--
Construct Atomikos UserTransactionManager, needed to configure
Spring
-->
<bean id="userTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"
init-method="init" destroy-method="close">
<!--
when close is called, should we force transactions to
terminate or not?
-->
<property name="forceShutdown">
<value>true</value>
</property>
</bean>
<!--
Also use Atomikos UserTransactionImp, needed to configure Spring
-->
<bean id="userTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">
<property name="transactionTimeout">
<value>300</value>
</property>
</bean>
<!--
Configure the Spring framework to use JTA transactions from
Atomikos
-->
<bean id="transactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager">
<ref bean="userTransactionManager" />
</property>
<property name="userTransaction">
<ref bean="userTransaction" />
</property>
</bean>
</beans>
xaDataSourceClassName是设置javax.sql.XADataSource(使用DB的驱动提供),其中xaProperties是Map类型的,通过反射设置javax.sql.XADataSource的属性。例子中使用的是DB2。