在上个公司由于项目的需要,新做的电子商务网站要与一个返款系统(之前做的)进行集成,要求新做的电子商务网站能够调用并修改返款系统的数据,当然这个两个数据库(oracle),部署在redhat tomcat下面,由于tomcat本身并不支持jta事物,加上项目用的是spring,因此在网上打捞一番后就用了jotm。
JOTM(Java Open Transaction Manager)是ObjectWeb的一个开源JTA实现,本身也是开源应用程序服务器JOnAS(Java Open Application Server)的一部分,为其提供JTA分布式事务的功能。Spring对JOTM提供了较好的支持,提供了一个org.springframework.transaction.jta.JotmFactoryBean的支持类,在Spring2.0中也包含了JOTM相关的一些library。
jotm的下载地址为http://jotm.objectweb.org,最新版本为JOTM_2_2_1.
下载完成后解压缩,然后打开jotm下面conf文件夹,拷贝carol.properties文件到classpath中,并修改这个文件如下
carol.properties
# jonas rmi acativation (iiop, irmi, jrmp, cmi) carol.protocols=jrmp carol.start.jndi=false carol.start.ns=false
上面配置文件的目的是不使用JNDI的方式来加载JOTM的配置,当然也可以根据需要选择其它的一些配置。
然后开始在Spring上下文中配置JOTM,在classpath中建立一个ApplicationContext-jotm.xml,配置如下
<?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="ds244" 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:@192.168.1.244:1521:db" /> </bean> </property> <property name="user" value="user11" /> <property name="password" value="123" /> </bean> <bean id="ds110" 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:@192.168.1.110:1521:shopdb" /> </bean> </property> <property name="user" value="user1" /> <property name="password" value="123" /> </bean> <bean id="template110" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="ds110" /> </bean> <bean id="template244" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="ds244" /> </bean> <bean id="dao110" class="dao.Dao110"> <property name="jdbcTemplate" ref="template110" /> </bean> <bean id="dao244" class="dao.Dao244"> <property name="jdbcTemplate" ref="template244" /> </bean> <bean id="jtaService" class="service.JtaService"> <property name="dao110" ref="dao110" /> <property name="dao244" ref="dao244" /> </bean> <tx:annotation-driven transaction-manager="txManager" /> </beans>
说明:
这里配置了两个标准的xa数据源,以及两个dao,具体代码如下:
Dao110.java
package dao; import org.springframework.jdbc.core.JdbcTemplate; public class Dao110 { private JdbcTemplate jdbcTemplate; public JdbcTemplate getJdbcTemplate() { return jdbcTemplate; } public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } public void changeName() { System.out.println("110 begin:"+this.jdbcTemplate); // jdbcTemplate.update("update aduser set username='admin' where id=92");//不可执行 jdbcTemplate.update("update aduser set username='adminddddd' where id=92"); System.out.println("110 after"); } }
Dao244.java
package dao; import org.springframework.jdbc.core.JdbcTemplate; public class Dao244 { private JdbcTemplate jdbcTemplate; public JdbcTemplate getJdbcTemplate() { return jdbcTemplate; } public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } public void changeName() { System.out.println("244 begin:"+this.jdbcTemplate); // jdbcTemplate.update("update aduser set username='zwls' where id=68");//不可执行 jdbcTemplate.update("update aduser set username='zwlsdasdsadsadad' where id=68"); System.out.println("244 after"); } }
JtaService.java
package service; import org.springframework.transaction.annotation.Transactional; import dao.Dao110; import dao.Dao244; @Transactional/* ①事务注解,以便Spring动态织入事务管理功能*/ public class JtaService { private Dao110 dao110; private Dao244 dao244; public void jtaTest() { System.out.println("jtatest"); System.out.println("dao110:"+dao110); System.out.println("dao244:"+dao244); dao110.changeName(); dao244.changeName(); } public Dao110 getDao110() { return dao110; } public void setDao110(Dao110 dao110) { this.dao110 = dao110; } public Dao244 getDao244() { return dao244; } public void setDao244(Dao244 dao244) { this.dao244 = dao244; } }
JtaAction.java
package action; import service.JtaService; import com.opensymphony.xwork2.ActionSupport; public class JtaAction extends ActionSupport{ private JtaService jtaService; @Override public String execute() throws Exception { System.out.println("execute"); System.out.println("jtaService"+jtaService); try { jtaService.jtaTest(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); System.out.println("ExceptionExceptionExceptionExceptionException"); } return super.execute(); } public JtaService getJtaService() { return jtaService; } public void setJtaService(JtaService jtaService) { this.jtaService = jtaService; } }