最近一个项目要跨多数据,配多数据源的,其中就用到了事务,毫无疑问我选择的是Spring的声明式JTA事务。我的环境是JBOSS+ORACLE 9I
自己私下做了些实验,不过还是成功了
实验一:MySQL 5.0
采用atomikos的jta事务(要感谢 http://andyao.iteye.com/)
<?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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<bean id="dataSource" class="com.atomikos.jdbc.SimpleDataSourceBean"
init-method="init" destroy-method="close">
<property name="uniqueResourceName">
<value>mysql/main</value>
</property>
<property name="xaDataSourceClassName">
<!--使用Mysql XADataSource(mysql>=5.0, Connector/J>=5.0才可以支持XADatasource)-->
<value>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</value>
</property>
<property name="xaDataSourceProperties">
<value>URL=jdbc:mysql://localhost:3306/crm?useUnicode=true&characterEncoding=UTF-8;user=root;password=root</value>
</property>
<property name="exclusiveConnectionMode">
<value>true</value>
</property>
<property name="connectionPoolSize">
<value>3</value>
</property>
<property name="validatingQuery">
<value>SELECT 1</value>
</property>
</bean>
<!-- 第二个数据库 -->
<bean id="dataSourceB" class="com.atomikos.jdbc.SimpleDataSourceBean"
init-method="init" destroy-method="close">
<property name="uniqueResourceName">
<value>mysql/news</value>
</property>
<property name="xaDataSourceClassName">
<!--
使用Mysql XADataSource(mysql>=5.0, Connector/J>=5.0才可以支持XADatasource)
-->
<value>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</value>
</property>
<property name="xaDataSourceProperties">
<value>URL=jdbc:mysql://localhost:3306/crm2?useUnicode=true&characterEncoding=UTF-8;user=root;password=root</value>
</property>
<property name="exclusiveConnectionMode">
<value>true</value>
</property>
<property name="connectionPoolSize">
<value>3</value>
</property>
<property name="validatingQuery">
<value>SELECT 1</value>
</property>
</bean>
<bean id="lobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler" />
<!-- 第一个数据库的sqlMapClient -->
<bean id="sqlMapClient1" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation">
<!-- 包含第一个数据库表的map -->
<value>classpath:SqlMapConfig.xml</value>
</property>
<property name="dataSource" ref="dataSource" />
<property name="lobHandler" ref="lobHandler" />
</bean>
<!-- 第二个数据库的sqlMapClient -->
<bean id="sqlMapClient2" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation">
<!-- 包含第一个数据库表的map -->
<value>classpath:SqlMapConfig2.xml</value>
</property>
<property name="dataSource" ref="dataSourceB" />
<property name="lobHandler" ref="lobHandler" />
</bean>
<!-- Optional: add a log administrator -->
<bean id="localLogAdministrator"
class="com.atomikos.icatch.admin.imp.LocalLogAdministrator"/>
<bean id="userTransactionService"
class="com.atomikos.icatch.config.UserTransactionServiceImp"
init-method="init" destroy-method="shutdownForce">
<constructor-arg>
<!-- IMPORTANT: specify all Atomikos properties here -->
<props>
<prop key="com.atomikos.icatch.service">com.atomikos.icatch.standalone.UserTransactionServiceFactory</prop>
</props>
</constructor-arg>
<property name="initialLogAdministrators">
<list>
<ref bean="localLogAdministrator"/>
</list>
</property>
</bean>
<!--Construct Atomikos UserTransactionManager,needed to configure Spring -->
<bean id="AtomikosTransactionManager"
class="com.atomikos.icatch.jta.UserTransactionManager"
init-method="init" destroy-method="close"
depends-on="userTransactionService">
<!--when close is called,should we force transactions to terminate or not?-->
<property name="forceShutdown" value="false" />
</bean>
<!--Also use Atomikos UserTransactionImp, needed to configure Spring-->
<bean id="AtomikosUserTransaction"
class="com.atomikos.icatch.jta.UserTransactionImp"
depends-on="userTransactionService">
<property name="transactionTimeout" value="300" />
</bean>
<!-- Configure the Spring framework to use JTA transactions from Atomikos -->
<bean id="JtaTransactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager"
depends-on="userTransactionService">
<property name="transactionManager" ref="AtomikosTransactionManager" />
<property name="userTransaction" ref="AtomikosUserTransaction" />
</bean>
<bean id="user1Dao" class="com.crm.code.dao.impl.User1DaoImpl">
<property name="sqlMapClient">
<ref bean="sqlMapClient1"/>
</property>
</bean>
<bean id="user2Dao" class="com.crm.code.dao.impl.User2DaoImpl">
<property name="sqlMapClient">
<ref bean="sqlMapClient2"/>
</property>
</bean>
<bean id="user12Service" class="com.crm.code.service.impl.User12ServiceImpl">
<property name="user1Dao">
<ref bean="user1Dao" />
</property>
<property name="user2Dao">
<ref bean="user2Dao" />
</property>
</bean>
</beans>
这样是成功的 可是切换oracle9i时悲剧发生了
--- Cause: com.atomikos.datasource.ResourceException: resume for XID oracle.jdbc.xa.OracleXid@145f939 raised -3: the XA resource detected an internal error
Caused by: com.ibatis.common.jdbc.exception.NestedSQLException:
--- The error occurred in ibatis/Product1.xml.
--- The error occurred while executing update.
--- Check the insert into boss_product (PROD_ID, PARENT_ID, APP_ID, PROD_NAME, PROD_CODE, DEFAULT_VER_PROD_ID, DATA_PATH, GMT_CREATED, GMT_MODIFIED, CREATOR, MODIFIER, IS_DELETED) values (seq_boss_product.nextval, 1, 88, ?, ?, 10, 'aaa', sysdate, sysdate, 'aavv', 'aacb', 'n') .
官方说oracle连接问题 哎。。。无语了
换了一种JTA事务机制 通过JOTM
<?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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<bean id="jotm" class="org.springframework.transaction.jta.JotmFactoryBean"/>
<bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="userTransaction" ref="jotm"/>
</bean>
<bean id="dataSourceA" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource"
destroy-method="shutdown">
<property name="dataSource">
<bean class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown">
<property name="transactionManager" ref="jotm"/>
<property name="driverName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@10.2.224.44:1521:trade"/>
</bean>
</property>
<property name="user" value="crm_aep"/>
<property name="password" value="crm_aep"/>
</bean>
<bean id="dataSourceB" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource"
destroy-method="shutdown">
<property name="dataSource">
<bean class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown">
<property name="transactionManager" ref="jotm"/>
<property name="driverName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@10.2.226.24:1521:voucher"/>
</bean>
</property>
<property name="user" value="boss"/>
<property name="password" value="boss"/>
</bean>
<tx:annotation-driven transaction-manager="txManager" proxy-target-class="true" />
<!-- 第一个数据库的sqlMapClient -->
<bean id="sqlMapClient1" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation">
<!-- 包含第一个数据库表的map -->
<value>classpath:SqlMapConfig_ora1.xml</value>
</property>
<property name="dataSource" ref="dataSourceA" />
</bean>
<!-- 第二个数据库的sqlMapClient -->
<bean id="sqlMapClient2" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation">
<!-- 包含第一个数据库表的map -->
<value>classpath:SqlMapConfig_ora2.xml</value>
</property>
<property name="dataSource" ref="dataSourceB" />
</bean>
<bean id="product1Dao" class="com.crm.code.dao.impl.Product1DaoImpl">
<property name="sqlMapClient">
<ref bean="sqlMapClient1"/>
</property>
</bean>
<bean id="product2Dao" class="com.crm.code.dao.impl.Product2DaoImpl">
<property name="sqlMapClient">
<ref bean="sqlMapClient2"/>
</property>
</bean>
<bean id="product12Service" class="com.crm.code.service.impl.Product12ServiceImpl">
<property name="product1Dao">
<ref bean="product1Dao" />
</property>
<property name="product2Dao">
<ref bean="product2Dao" />
</property>
</bean>
</beans>
成功了。。。
很好很好 哈哈哈
分享到:
相关推荐
JTA配置文件请看applicationContext-jta.xml 博文链接:https://liran-email.iteye.com/blog/227990
在Spring中使用JTA事务管理 1 通过集成JOTM,直接在Spring中使用JTA事务 1.1. 将JOTM以下类库添加到类路径中 1.2. 编写JOTM配置文件,放到类路径下 1.3. 在MySQL上建立两个数据库 1.4. 在Spring配置文件中配置JOTM ...
Spring+iBatis+JOTM实现JTA事务: 如何处理跨库事物:spring + jtom 的jta事务是个很好的选择. 这个源码示例非常不错,包括所有的源码和jar包,下载后eclipse 或 myeclipse 导入就能用。 里面有详细的说明和注释,...
spring + JTA + JOTM实现分布式事务, 高大上的技术
JTA(Java Transaction API) 为 J2EE 平台提供了分布式事务服务。 要用 JTA 进行事务界定,应用程序要调用 javax.transaction.UserTransaction 接口中的方法。
Spring+iBatis+JOTM实现JTA事务
多数据源 更新 spring jta java jotm
NULL 博文链接:https://zhaoshijie.iteye.com/blog/1836707
1.利用mina框架重构api,脱离了web应用服务器resin,而原api的jta事务由resin支持,故需要用其他支持jta事务的工具重新配置。在支持jta事务的工具中选择了atomikos 2.Api的数据库连接配置参数没有类似:testQuery的...
在tomcat 中配置JTA 事务,方便管理web项目
有关JDBC事务 JTA事务 传播特性 隔离级别等等
spring + JTA + atomikos实现分布式事务, 高大上的技术
spring+jms+jta事务的消息发送和消息消费。 完整可正常运行例子,对JTA分布式事务的配置。 本例可以直接作为处理消息的项目,在此之上直接继续开发。
2.Spring+Jotm整合实现JTA分布式事务,应用场景如转账等,同一事务内完成db1用户加100元、db2用户减100元。 3.Spring+Junit4单元测试,优点:不会破坏数据库现场,等等。 (特别注意:Spring3.0里不在提供对jotm的...
分布式事务操作之Spring+JTA+mybatis源码
Java分布式开发spring+jta+jotm,可用 Java分布式开发spring+jta+jotm,可用
JTA分布式事务处理多数据事务问题的示例代码。
Spring Boot+Druid+Mybatis实现JTA分布式事务
NULL 博文链接:https://latex.iteye.com/blog/1732783