使用spring+atomikos+ibatis实现声明式DB2多数据库全局分布式事务

使用spring+atomikos+ibatis实现声明式DB2多数据库全局分布式事务,关键是DB2数据库驱动程序和数据库访问参数的配置。db2的jdbc driver有好几种,不同的driver,参数的写法也不同,甚至端口也不一样,而且本人使用的DB2 V8.2驱动程序db2jcc.jar有bug,必须使用fp12版本的db2jcc.jar代替,才能实现全局分布式事务
atomikos官网上没有提供DB2的配置示例,试了多次,以下配置终于搞定了全局分布式事务,见其中的注释

<tx:advice id="txAdvice" transaction-manager="txManager">
		<tx:attributes>
			<tx:method name="get*" read-only="true" />
			<tx:method name="*" rollback-for="Throwable"/>
		</tx:attributes>
	</tx:advice>
	
	<!-- 在类foo.bar.MyClass的myMethod()方法里实现全局分布式事务,该方法对两个数据源进行操作 -->
	<aop:config>
		<aop:pointcut id="myOperation"
			expression="execution(*foo.bar.MyClass.myMethod(..))" />
		<aop:advisor advice-ref="txAdvice"
			pointcut-ref="myOperation" />
	</aop:config>
	
	<!-- 数据源1 -->
	<bean id="dataSource"
		class="com.atomikos.jdbc.AtomikosDataSourceBean">
		<property name="uniqueResourceName">
			<value>app/main</value>
		</property>
		<property name="xaDataSourceClassName">
			<value>[b]com.ibm.db2.jcc.DB2XADataSource[/b]</value>
		</property>

		<property name="xaProperties">
			<props>
				[b]<prop key="serverName">172.160.1.138</prop>
				<prop key="portNumber">50000</prop>
				<prop key="databaseName">MYDB</prop>
				<prop key="user">db2admin</prop>
				<prop key="password">pass</prop>
				<prop key="driverType">4</prop>[/b]
			</props>
		</property>
		<property name="poolSize">
			<value>5</value>
		</property>
	</bean>
	
	<!-- 数据源2 -->
	<bean id="dataSourceHis"
		class="com.atomikos.jdbc.AtomikosDataSourceBean">
		<property name="uniqueResourceName">
			<value>app/history</value>
		</property>
		<property name="xaDataSourceClassName">
			<value>com.ibm.db2.jcc.DB2XADataSource</value>
		</property>

		<property name="xaProperties">
			<props>
				<prop key="serverName">172.160.1.139</prop>
				<prop key="portNumber">50000</prop>
				<prop key="databaseName">NDB</prop>
				<prop key="user">db2admin</prop>
				<prop key="password">pass</prop>
				<prop key="driverType">4</prop>
			</props>
		</property>
		<property name="poolSize">
			<value>5</value>
		</property>
	</bean>
	
	<!-- 数据源1的iBatis sqlMapClient -->
	<bean id="sqlMapClient1"
		class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
		<property name="configLocation">
			<value>SqlMapConfig.xml</value>
		</property>
		<property name="dataSource">
			<ref bean="dataSource" />
		</property>
	</bean>

	<!-- 数据源2的iBatis sqlMapClient -->
	<bean id="sqlMapClient2"
		class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
		<property name="configLocation">
			<value>SqlMapConfig.xml</value>
		</property>
		<property name="dataSource">
			<ref bean="dataSourceHis" />
		</property>
	</bean>
	
	<bean id="atomikosTransactionManager"
		class="com.atomikos.icatch.jta.UserTransactionManager"
		init-method="init" destroy-method="close">
		<property name="forceShutdown">
			<value>true</value>
		</property>
	</bean>

	<bean id="atomikosUserTransaction"
		class="com.atomikos.icatch.jta.UserTransactionImp">
		<property name="transactionTimeout" value="240" />
	</bean>

	<bean id="txManager"
		class="org.springframework.transaction.jta.JtaTransactionManager">
		<property name="transactionManager">
			<ref bean="atomikosTransactionManager" />
		</property>
		<property name="userTransaction">
			<ref bean="atomikosUserTransaction" />
		</property>
	</bean>
	<-- 访问数据源1的dao -->
	<bean id="dao1" class="foo.bar.dao.My1DAOImpl">
		<property name="sqlMapClient">
			<ref bean="sqlMapClient" />
		</property>
	</bean>
	<-- 访问数据源2的dao -->
	<bean id="dao2" class="foo.bar.dao.My2DAOImpl">
		<property name="sqlMapClient">
			<ref bean="sqlMapClientHis" />
		</property>
	</bean>


iBatis的配置没有特殊的地方,使用abator for iBatis自动生成,abatorConfig.xml里daoGenerator的type属性设置为'SPRING'

你可能感兴趣的:(DAO,spring,Hibernate,ibatis,db2)