添加配置文件ApplicationContext-jotm.xml到src下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"> <!-- XA Datasource --> <bean id="datasource1" class="com.atomikos.jdbc.SimpleDataSourceBean" init-method="init" destroy-method="close"> <property name="uniqueResourceName"> <value>mysql/main</value> </property> <property name="xaDataSourceClassName"> <value>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</value> </property> <property name="xaDataSourceProperties"> <value>URL=jdbc:mysql://192.168.0.229:3306/hdb;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="datasource2" class="com.atomikos.jdbc.SimpleDataSourceBean" init-method="init" destroy-method="close"> <property name="uniqueResourceName"> <value>mysql/news</value> </property> <property name="xaDataSourceClassName"> <value>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</value> </property> <property name="xaDataSourceProperties"> <value>URL=jdbc:mysql://192.168.0.229:3306/hdb2;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="template1" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="datasource1" /> </bean> <bean id="template2" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="datasource2" /> </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="300"/> </bean> <bean id="springTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"> <property name="transactionManager"><ref bean="atomikosTransactionManager" /></property> <property name="userTransaction"><ref bean="atomikosUserTransaction" /></property> </bean> <bean id="dao1" class="test.UserDao1"> <property name="jdbcTemplate"> <ref bean="template1"></ref> </property> </bean> <bean id="dao2" class="test.UserDao2"> <property name="jdbcTemplate"> <ref bean="template2"></ref> </property> </bean> <!-- --> <bean id="userServiceTarget" class="test.UserServiceImpl"> <property name="dao1" ref="dao1"/> <property name="dao2" ref="dao2"/> </bean> <bean id="userTest" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <property name="transactionManager"> <ref bean="springTransactionManager"/> </property> <property name="target"> <ref bean="userServiceTarget"/> </property> <property name="transactionAttributes"> <props> <prop key="insert*">PROPAGATION_REQUIRED,-Exception</prop> </props> </property> </bean> </beans>
carol.properties放在src下:
carol.start.jndi=false carol.start.ns=false carol.jndi.java.naming.factory.url.pkgs=org.apache.naming
jta.properties也放在src下:
com.atomikos.icatch.service=com.atomikos.icatch.standalone.UserTransactionServiceFactory com.atomikos.icatch.console_file_name = tm.out com.atomikos.icatch.log_base_name = tmlog com.atomikos.icatch.tm_unique_name = com.atomikos.spring.jdbc.tm com.atomikos.icatch.console_log_level =INFO
到此配置成功,下面是测试
Userdao1
public class UserDao1 extends JdbcDaoSupport { public void insertData(String id, String name) { String sxqlString = "insert into xa_test(id,name) values('" + id + "','" + name + "')"; System.out.println("打印sql: "+sxqlString); getJdbcTemplate().execute(sxqlString); } }
Userdao2
public class UserDao2 extends JdbcDaoSupport { public void insertData(String id,String name){ String sxqlString = "insert into xa_test(id,name) values('"+ id +"','"+name+"')"; System.out.println("打印sql: "+sxqlString); getJdbcTemplate().execute(sxqlString); } }
UserService
public interface UserService { public void insertBothDatabase(String id,String name) throws Exception; public void insert1Database(String id, String name)throws Exception; public void insert2Database(String id, String name)throws Exception; }
UserServiceImpl
@Transactional public class UserServiceImpl implements UserService { private UserDao1 dao1; private UserDao2 dao2; public void insertBothDatabase(String id, String name) throws Exception { dao1.insertData(id, name); dao2.insertData(id, name); } public void insert1Database(String id, String name) throws Exception { dao1.insertData(id, name); } public void insert2Database(String id, String name) throws Exception { dao2.insertData(id, name); } public UserDao1 getDao1() { return dao1; } public void setDao1(UserDao1 dao1) { this.dao1 = dao1; } public UserDao2 getDao2() { return dao2; } public void setDao2(UserDao2 dao2) { this.dao2 = dao2; } }
main方法测试,注意main方法的测试需要添加上相应的jar:
ApplicationContext ctx = new FileSystemXmlApplicationContext( "classpath:ApplicationContext-jotm.xml"); // 多库userTest // 库2 userTest2 UserService ut = (UserService) ctx.getBean("userTest2"); try { //ut.insertBothDatabase("2", "11111111112222"); String s = "111111111122222222223333333333"; System.out.println(s.length()); //ut.insertBothDatabase("3", s); //ut.insert2Database("2", "22222test");// 单独操作数据库2 } catch (Exception e) { System.out.println("跨库事务回滚,两个库都未插入数据"); } finally { System.out.println("结束"); }
而WEB服务器环境中可以用Action测试,超链接如下:
<br/><a href = "/hpr/hcinfo/Com_showinfo.action?sid=ku2">只向库2添加数据</a> <br/><a href = "/hpr/hcinfo/Com_showinfo.action?sid=asdf">忘两个库都添加数据,都不是非法数据</a> <br/><a href = "/hpr/hcinfo/Com_showinfo.action?sid=yigefeifafa">忘两个库添加数据,符合库1添加数据要求,对库2是非法数据</a>
测试代码:
ApplicationContext ctx = new FileSystemXmlApplicationContext(
"classpath:ApplicationContext-jotm.xml");
// 多库userTest // 库2 userTest2
String a="userTest";
boolean boo = sid.equals("ku2");
if (boo) {
a = a+"2";
}
UserService ut = (UserService) ctx.getBean(a);
try {
//ut.insertBothDatabase("2", "11111111112222");
String s = "111111111122222";
if(boo){
ut.insert2Database("2", s);// 单独操作数据库2
}else{
if(sid.equals("asdf")){
ut.insertBothDatabase("3", s);
}else{
// 忘两个数据库插入非法数据,对库1符合要求,库2不符合要求
ut.insertBothDatabase("3", s + s );
}
}
//
} catch (Exception e) {
System.out.println("跨库事务回滚,两个库都未插入数据");
} finally {
System.out.println("结束");
}
WEB服务器是tomcat,一开始我把所有的jotm的jar都放进来啦,但是我发现我一个一个去了之后都丝毫不影响。到spring的jar包一看,spring-tx-2.5.6.jar竟然有支持JTOM的类,org.springframework.transaction.jta.JotmFactoryBean.class 遂恍然大悟,Spring真是强大无比。所以我没有添加任何的其他的jar。两个数据库的表都是xa_test(id,name)不同的是库1的name长度为40,而库2的长度为20. 两个库同事操作的时候如果其中一个库不符合要求,两个库的操作都不执行。这也是所谓的跨库事务。
相关推荐
spring + JTA + JOTM实现分布式事务, 高大上的技术
Spring+iBatis+JOTM实现JTA事务 spring ibatis jotm 分布 事务 多数据源
简单易懂的JOTM实现分布式事务控制,此代码是maven项目,如果需要jar可以邮件给我,我发给你。
spring+jotm 多数据源事务管理(二)hibernate 使用hibernate关联jotm也很方便,先看一个没有使用jotm的例子:
NULL 博文链接:https://zhaoshijie.iteye.com/blog/1836707
使用JOTM完成多数据源事务管理 在上一篇文档《Spring事务学习文档 》中,在最后我们说到了有两种方法来解决分布式事务,接下来,我们就简单说一下如何使用JOTM来管理分布式事务。
2.Spring+Jotm整合实现JTA分布式事务,应用场景如转账等,同一事务内完成db1用户加100元、db2用户减100元。 3.Spring+Junit4单元测试,优点:不会破坏数据库现场,等等。 (特别注意:Spring3.0里不在提供对jotm的...
1 通过集成JOTM,直接在Spring中使用JTA事务 1.1. 将JOTM以下类库添加到类路径中 1.2. 编写JOTM配置文件,放到类路径下 1.3. 在MySQL上建立两个数据库 1.4. 在Spring配置文件中配置JOTM 1.5. 在Spring中运行测试 2 ...
JOTM (Java Open Transaction Manager)是由ObjectWeb协会开发的功能完整的且资源开放的独立的事务管理器。 它提供了 JAVA 应用程序的事务支持,而且与 JTA( JAVA 事务 API)兼容。您可以在JOTM home page 了解到更...
spring+jotm 多数据源事务管理(三)JNDI+Tomcat 首先需要将jotm相关jar包加入到tomcat中,如下: o jotm.jar o jotm_jrmp_stubs.jar o ow_carol.jar o jta.jar o jta-spec1_0_1.jar o jts1_0.jar o objectweb-...
JOTM Spring分布式事务处理(多数据源) demo配置 JOTM Spring分布式事务处理(多数据源) demo配置
代码下载下来,想要了解更多相关内容可以看http://www.cnblogs.com/shamo89/p/7307961.html
原先很多都是用jotm实现的,但是由于spring的升级,totm的本地化实例那个类已经找不到了,所以我使用了atomikos。 因为xa接口的事务开销比较大,在项目中如果全部使用分布式的话,那么开销也是很大的,所以在项目中...
JOTM使用包 博文链接:https://log-cd.iteye.com/blog/807607
例子虽小,可覆盖面广,设计spring载入.properties文件,spring配置jta和jotm分布式事务,设置数据源连接池,注解事务驱动。功能是在mysql上建立了两个数据库分别为dbone和dbtwo,在dbone里有表tb1,表中只有一个字段...
如何处理跨库事物:spring + jtom 的jta事务是个很好的选择. 这个源码示例非常不错,包括所有的源码和jar包,下载后eclipse 或 myeclipse 导入就能用。 里面有详细的说明和注释,欢迎下载传播。有问题请在评价中...
JFile 是 JActor 的文件持久化组件,以及一个高吞吐量的可靠事务日志组件。 Google地图JSP标签库 利用Google:maps JSP标签库就能够在你的Web站点上实现GoogleMaps的所有功能而且不需要javascript或AJAX编程。它还...
JFile 是 JActor 的文件持久化组件,以及一个高吞吐量的可靠事务日志组件。 Google地图JSP标签库 利用Google:maps JSP标签库就能够在你的Web站点上实现GoogleMaps的所有功能而且不需要javascript或AJAX编程。它还...
JFile 是 JActor 的文件持久化组件,以及一个高吞吐量的可靠事务日志组件。 Google地图JSP标签库 利用Google:maps JSP标签库就能够在你的Web站点上实现GoogleMaps的所有功能而且不需要javascript或AJAX编程。它还...