`

Spring 中集成 JOTM 配置 JTA 事务

 
阅读更多

 

Spring 中集成 JOTM 配置 JTA 事务:

假如业务中要用到多个数据库,我们希望在业务方法中,当对某一个数据库的数据表进行操作的事务失败并回退(rollback),另外某一个数据库的数据表的操作事务也要回退,但应用一般的事务管理达不到这样的事务管理效果,这就需要实现 JTA 事务管理了。
这里我们在SPring中集成 Object web 的一个开源JTA实现JOTM (可以在http://jotm.objectweb.org 下载完整版) 来实现JTA事务管理。

1、将必须的类包放入类路径中:
 jotm.jar, xapool.jar, jotm_jrmp_stubs.jar, jta-spect1_0_1.jar, connector-1_5.jar等等。

2、编写JOTM配置文件carol.properties,将其放到类路径下:

Java代码
  1. #JNDI调用协议   
  2. carol.protocols=jrmp   
  3. #不使用CAROL JNDI封装器   
  4. carol.start.jndi= false   
  5. #不启动命名服务器   
  6. carol.start.ns= false   

 
3、在MYSQL中创建两个数据库 "jtatesta","jtatestb":

Java代码
  1. CREATE DATABASE IF NOT EXISTS jtatesta;   
  2. USE jtatesta;   
  3.   
  4. DROP TABLE IF EXISTS `user`;   
  5. CREATE TABLE `user` (   
  6.   `user_id`  int ( 10 ) unsigned NOT NULL auto_increment,   
  7.   `user_name` varchar( 45 ) NOT NULL,   
  8.   `user_password` varchar( 45 ) NOT NULL,   
  9.   PRIMARY KEY  (`user_id`)   
  10. ) ENGINE=InnoDB AUTO_INCREMENT= 5  DEFAULT CHARSET=latin1;   
  11.   
  12. INSERT INTO `user` (`user_id`,`user_name`,`user_password`) VALUES    
  13.  ( 1 , 'tufu' , 'tufu' );   
  14.   
  15. CREATE DATABASE IF NOT EXISTS jtatestb;   
  16. USE jtatestb;   
  17.   
  18. DROP TABLE IF EXISTS `grade`;   
  19. CREATE TABLE `grade` (   
  20.   `grade_id`  int ( 10 ) unsigned NOT NULL auto_increment,   
  21.   `user_id`  int ( 10 ) unsigned NOT NULL,   
  22.   `grade`  double  NOT NULL,   
  23.   PRIMARY KEY  (`grade_id`)   
  24. ) ENGINE=InnoDB AUTO_INCREMENT= 9  DEFAULT CHARSET=latin1;   
  25.   
  26. INSERT INTO `grade` (`grade_id`,`user_id`,`grade`) VALUES    
  27.  ( 1 , 0 , 100 );  

 
4、域对象、数据访问类和其他事务管理的一样,如:

Java代码
  1. //Domain对象User.java:   
  2. package  com.domain;   
  3. import  java.io.Serializable;   
  4. public   class  User  implements  Serializable {   
  5.      private   int  user_id;   
  6.      private  String user_name;   
  7.      private  String user_password;   
  8. ...... //省略set、get方法   
  9. }   
  10.   
  11. //Domain对象Grade.java:   
  12. package  com.domain;   
  13. import  java.io.Serializable;   
  14. public   class  Grade  implements  Serializable{   
  15.      private   int  grade_id;   
  16.      private  User user;   
  17.      private   double  grade;   
  18. ..... //省略set、get方法   
  19. }   
  20.   
  21. 应用Spring JDBC的DAO:(省略DAO接口)   
  22. //UserJdbcDao.java:   
  23. package  com.dao.jdbc;   
  24. import  org.springframework.jdbc.core.support.JdbcDaoSupport;   
  25. import  com.dao.UserDao;   
  26. import  com.domain.User;   
  27. public   class  UserJdbcDao  extends  JdbcDaoSupport  implements  UserDao{   
  28.      public   void  addUser(User user){   
  29.         String SQL =  "INSERT INTO user(user_id,user_name,user_password) VALUES(?,?,?)" ;   
  30.         Object[] params =  new  Object[]{   
  31.             user.getUser_id(),user.getUser_name(),user.getUser_password()   
  32.         };   
  33.          this .getJdbcTemplate().update(SQL, params);   
  34.     }   
  35. }   
  36. //GradeJdbcDao.java:   
  37. package  com.dao.jdbc;   
  38. import  com.dao.GradeDao;   
  39. import  com.domain.Grade;   
  40. import  org.springframework.jdbc.core.support.JdbcDaoSupport;   
  41. public   class  GradeJdbcDao  extends  JdbcDaoSupport  implements  GradeDao{   
  42.      public   void  addGrade(Grade grade){   
  43.          final  String SQL =  "INSERT INTO grade(user_id,grade) VALUES(?,?)" ;   
  44.         Object[] params =  new  Object[]{   
  45.             grade.getUser().getUser_id(),grade.getGrade()   
  46.         };   
  47.          this .getJdbcTemplate().update(SQL, params);   
  48.     }   
  49. }  

 
5、应用了JTA事务管理的业务类(省略了接口),用@Transactional注解标注,以在配置文件中可以用<tx:annotation-driven>注解驱动自动进行事务增强:

Java代码
  1. package  com.service.impl;   
  2. import  com.dao.GradeDao;   
  3. import  com.dao.UserDao;   
  4. import  com.domain.*;   
  5. import  org.springframework.transaction.annotation.Transactional;   
  6. import  com.service.MyService;   
  7. @Transactional   
  8. public   class  MyServiceImpl  implements  MyService {   
  9.      private  UserDao userDao;   
  10.      private  GradeDao gradeDao;   
  11.      public   void  setUserDao(UserDao userDao){   
  12.          this .userDao = userDao;   
  13.     }   
  14.      public   void  setGradeDao(GradeDao gradeDao){   
  15.          this .gradeDao = gradeDao;   
  16.     }   
  17.      @Transactional (readOnly= false )   
  18.      public   void  addGrade(User user,Grade grade){   
  19.          //假如希望两个添加数据的事务,其中有一个添加失败时,均回滚,   
  20.          //由于两个操作是在两个不同的数据库上进行的,故要JTA事务来进行管理   
  21.          //否则,将会出现添加一个,回滚一个的情形   
  22.         gradeDao.addGrade(grade);    
  23.         userDao.addUser(user);   
  24.     }   
  25. }  

 
6、spring为JOTM提供了一个org.springframework.transaction.jta.JotmFactoryBean 支持类,可以用其方便地创建本地JOTM实例。
具体的配置文件app_jta.xml如下:

Xml代码
  1. <? xml   version = "1.0"   encoding = "UTF-8" ?>   
  2. < beans   xmlns = "http://www.springframework.org/schema/beans"   
  3.      xmlns:xsp = "http://www.w3.org/2001/XMLSchema-instance"   
  4.      xmlns:aop = "http://www.springframework.org/schema/aop"   
  5.      xmlns:tx = "http://www.springframework.org/schema/tx"   
  6.      xsp:schemaLocation ="http://www.springframework.org/schema/beans   
  7.     http://www.springframework.org/schema/beans/spring-beans-2.0.xsd   
  8.     http://www.springframework.org/schema/aop   
  9.     http://www.springframework.org/schema/aop/spring-aop-2.0.xsd   
  10.     http://www.springframework.org/schema/tx   
  11.     http://www.springframework.org/schema/tx/spring-tx-2.0.xsd" >   
  12.     <!--JOTM本地实例-->   
  13.      < bean   id = "jotm"   class = "org.springframework.transaction.jta.JotmFactoryBean" />   
  14.      <!--JTA事务管理器-->   
  15.      < bean   id = "txManager"   class = "org.springframework.transaction.jta.JtaTransactionManager" >   
  16.          < property   name = "userTransaction"   ref = "jotm" /> <!--指定userTransaction属性引用JOTM本地实例-->   
  17.      </ bean >   
  18.     <!--XAPool配置,内部包含了一XA数据源,对应了数据库jtatesta   
  19.     支持JTA事务的数据源,必须封装成XAPool-- >   
  20.      < bean   id = "jtaTestADS"   class = "org.enhydra.jdbc.pool.StandardXAPoolDataSource"   
  21.      destroy-method = "shutdown" >   
  22.          < property   name = "dataSource" > <!--内部XA数据源-->   
  23.              < bean   class = "org.enhydra.jdbc.standard.StandardXADataSource"   
  24.              destroy-method = "shutdown" >   
  25.                  < property   name = "transactionManager"   ref = "jotm" />   
  26.                  < property   name = "driverName"   value = "com.mysql.jdbc.Driver" />   
  27.                  < property   name = "url"   value = "jdbc:mysql://localhost/jtatesta" />   
  28.              </ bean >   
  29.          </ property >   
  30.          < property   name = "user"   value = "root" />   
  31.          < property   name = "password"   value = "885123" />   
  32.      </ bean >   
  33.      <!--类似地,对应了数据库jtatestb的XAPool配置,内部包含了一XA数据源-->   
  34.      < bean   id = "jtaTestBDS"   class = "org.enhydra.jdbc.pool.StandardXAPoolDataSource"   
  35.      destroy-method = "shutdown" >   
  36.          < property   name = "dataSource" > <!--内部XA数据源-->   
  37.              < bean   class = "org.enhydra.jdbc.standard.StandardXADataSource"   
  38.              destroy-method = "shutdown" >   
  39.                  < property   name = "transactionManager"   ref = "jotm" />   
  40.                  < property   name = "driverName"   value = "com.mysql.jdbc.Driver" />   
  41.                  < property   name = "url"   value = "jdbc:mysql://localhost/jtatestb" />   
  42.              </ bean >   
  43.          </ property >   
  44.          < property   name = "user"   value = "root" />   
  45.          < property   name = "password"   value = "885123" />   
  46.      </ bean >   
  47.   
  48.      <!--分别配置访问jtaTestADS、jtaTestBDS数据源的Spring JDBC模板-->   
  49.      < bean   id = "jtaTestATemplate"   class = "org.springframework.jdbc.core.JdbcTemplate" >   
  50.          < property   name = "dataSource"   ref = "jtaTestADS" />   
  51.      </ bean >   
  52.      < bean   id = "jtaTestBTemplate"   class = "org.springframework.jdbc.core.JdbcTemplate" >   
  53.          < property   name = "dataSource"   ref = "jtaTestBDS" />   
  54.      </ bean >   
  55.   
  56.      <!--分别配置基于模板jtaTestADS,jtaTestBDS的DAO-->   
  57.      < bean   id = "userDao"   class = "com.dao.jdbc.UserJdbcDao" >   
  58.          < property   name = "jdbcTemplate"   ref = "jtaTestATemplate" />   
  59.      </ bean >   
  60.      < bean   id = "gradeDao"   class = "com.dao.jdbc.GradeJdbcDao" >   
  61.          < property   name = "jdbcTemplate"   ref = "jtaTestBTemplate" />   
  62.      </ bean >   
  63.   
  64.      <!--跨数据库的JTA事务的业务类-->   
  65.      < bean   id = "myService"   class = "com.service.impl.MyServiceImpl" >   
  66.          < property   name = "userDao"   ref = "userDao" />   
  67.          < property   name = "gradeDao"   ref = "gradeDao" />   
  68.      </ bean >   
  69.   <!--注解事务驱动-->   
  70.      < tx:annotation-driven   transaction-manager = "txManager"   proxy-target-class = "true" />   
  71.   
  72. </ beans >   

 

7、测试main方法:

Java代码
  1. import  com.service.MyService;   
  2. import  com.service.impl.MyServiceImpl;   
  3. import  com.domain.*;   
  4. import  org.springframework.context.support.ClassPathXmlApplicationContext;   
  5.   
  6. public   class  TestMain {   
  7.      public   static   void  main(String args[]){   
  8.         ClassPathXmlApplicationContext ctx =   
  9.                  new  ClassPathXmlApplicationContext( "beans_jta.xml" );   
  10.         MyService ms = (MyServiceImpl)ctx.getBean( "myService" );   
  11.         User user =  new  User();   
  12. //特意添加一个重复的主键,以使添加user的事务失败并回退   
  13. //如果此时应用JTA事务失败,将仍会执行添加grade的事务并提交(前提是先于添加user操作)   
  14. //如果应用JTA事务成功,就会两个添加事务同时执行或同时回退。   
  15.         user.setUser_id( 1 );    
  16.         user.setUser_name( "tufu" );   
  17.         user.setUser_password( "tufu" );   
  18.         Grade grade =  new  Grade();   
  19.         grade.setGrade( 100 );   
  20.         grade.setUser(user);   
  21.   
  22.         ms.addGrade(user,grade);   
  23.     }   
  24. }   
  25.   
  26.    

 注:将log4j.properties中的log4j日志设置为DEBUG级别,可以看到详细的JTA事务执行情况:
.......
log4j.rootLogger=DEBUG,R,A1
.......

 

 在特定应用服务器使用JTA
    一般来说,Spring的事务抽象与应用服务器是无关的。不过,如果你如果希望事务管理器使用特定的UserTransaction 和 TransactionManager 对象(可以被自动探测),以获取更多的增强事务语义。这时,针对不同的Java EE应用服务器,Spring的事务管理器可以采取不同的配置。 3 d0 W4 y5 k3 u, h! G

 BEA WebLogic

    在一个使用WebLogic 7.0、8.1或更高版本的环境中,你一般会优先选用特定于WebLogic的 WebLogicJtaTransactionManager 类来取代基础的 JtaTransactionManager 类,因为在WebLogic环境中,该类提供了对Spring事务定义的完全支持,超过了标准的JTA语义。你可以使用以下的配置达到目的:
<bean id="txManager" class="org.springframework.transaction.jta.WebLogicJtaTransactionManager"/> 7 n6 e" n' j: m9 X- Q
它的特性包括:支持事务名,支持为每个事务定义隔离级别,以及在任何环境下正确地恢复事务的能力。

 IBM WebSphere
. |' v# o% K7 }( K& B
    在WebSphere 5.1、5.0和4.x环境下,你可以使用Spring的 WebSphereTransactionManagerFactoryBean 类。这是一个工厂类,通过WebSphere的静态访问方法(每个版本的WebSphere中都不同)获取到JTA TransactionManager 实例。一旦通过工厂bean获取到JTA TransactionManager 实例,就可以使用该实例装配一个Spring的 JtaTransactionManager bean,它封装了JTA UserTransaction,提供增强的事务语义。你可以按以下方式进行配置: 8 |6 Y+ C: C: k6 C

①引用WebSphere的JTA事务管理器

< bean id = " wsJtaTm " class = " org.springframework.transaction.jta.WebSphereTransactionManagerFactoryBean " />

< bean id = " transactionManager " class = " org.springframework.transaction.jta.JtaTransactionManager " >

< property name = " transactionManager ref= " wsJtaTm " />

</ bean >

    小结
    你既可以在没有任务应用服务器支持的情况下,直接通过集成JOTM在Spring中使用JTA事务管理,也可以通过引用Java EE应用服务器的JNDI数据源,利用应用服务器提供的JTA事务功能间接实现Spring 中的JTA事务管理。为了利用一些高级Java EE应用服务器的JTA事务高级功能,你可以通过Spring所提供的特定于应用服务器的JTA事务管理器进行配置。

 

分享到:
评论

相关推荐

    Spring+iBatis+JOTM实现JTA事务

    通过这样的配置和测试,我们可以验证Spring+iBatis+JOTM的JTA事务管理功能是否正常工作。这种方式特别适用于需要在非J2EE容器中实现分布式事务的场景,为应用提供了强大的事务管理能力。然而,需要注意的是,JTA事务...

    spring JTA集成JOTM或Atomikos配置分布式事务(Tomcat应用服务器)

    3. **Spring配置**:在Spring的配置文件中,使用`jee:jta-data-source`或`jee:resource-ref`元素来引用之前创建的JNDI数据源,并配置`PlatformTransactionManager`为`org.objectweb.jotm.CurrentJOTM`。 **Atomikos...

    spring + JTA + JOTM实现分布式事务

    对于分布式事务,Spring支持JTA事务管理,并且可以无缝集成JOTM。 1. **配置JOTM**:首先,你需要在项目的类路径下添加JOTM的依赖库。然后,在Spring的配置文件中定义JOTM的事务管理器 bean,例如: ```xml ...

    多数据源 更新 spring jta java jotm

    要在Spring中配置JOTM,首先添加JOTM和Spring的JTA依赖到项目中。然后,定义一个`PlatformTransactionManager` bean,使用`JotmFactoryBean`来创建JOTM实例。这样,Spring就可以利用JOTM管理事务,确保在多数据源...

    在Spring中使用JTA事务管理

    本文将详细介绍如何在Spring中使用JTA事务管理,包括通过集成JOTM(Java Open Transaction Manager)以及引用Tomcat的JTA事务。 ### 1. 通过集成JOTM,直接在Spring中使用JTA事务 #### 1.1. 添加JOTM类库到类路径...

    Java分布式开发spring+jta+jotm

    JOTM可以在Spring框架中无缝集成,通过Spring的PlatformTransactionManager接口来配置和使用。 **Spring 配置JTA和JOTM** 在Spring中使用JTA和JOTM,首先需要在项目中引入JOTM的依赖。接着,你需要配置Spring的`...

    spring+jotm 多数据源事务管理(二)hibernate

    在Spring中集成JOTM可以提供更高级别的事务控制,确保在多数据源环境下事务的一致性和完整性。 首先,我们需要了解在没有使用JOTM时,Spring与Hibernate的常规配置。在提供的XML配置代码中,可以看到Spring配置了一...

    Spring+JOTM 分布式事务管理

    Spring框架作为一个广泛使用的Java应用程序开发框架,提供了多种支持事务管理的解决方案,其中包括集成JOTM(Java Open Transaction Manager)来处理分布式事务。本文将深入探讨Spring与JOTM结合使用的知识点,帮助...

    spring 3.0.5 + jotm 实现的的spring mvc 的例子

    在Spring中,通过集成JOTM,可以实现全局的事务控制,确保在多资源操作中保持数据的一致性。 **集成步骤**: 1. **添加依赖**:首先,项目需要在构建配置(如pom.xml或build.gradle)中引入Spring 3.0.5和JOTM的...

    spring+jotm 多数据源事务管理(三)JNDI+Tomcat

    在Tomcat中配置JNDI资源,以便Spring可以使用这些数据源。具体的XML配置如下: ```xml auth="Container" factory="org.objectweb.jndi.DataSourceFactory" type="javax.sql.DataSource" driverClassName=...

    spring-hibernate-jotm 例子

    而“jotm-2.0.10”则是JOTM的具体版本,包含其核心组件和必要的依赖,用于在Spring环境中配置和使用JOTM。 为了运行这个示例,你需要将这些jar包添加到你的项目类路径中,然后配置Spring的事务管理器为JOTM,并配置...

    Spring分布式事务实现

    在Spring中集成JOTM,可以利用其功能来管理跨数据库的事务。 JOTM相关的jar包包括`jotm-core.jar`,`xapool.jar`,`ow2-connector-1.5-spec.jar`和`ow2-jta-1.1-spec.jar`。这些库提供了JOTM的核心实现和连接池支持...

    使用JOTM实现分布式事务管理(多数据源)

    此外,JOTM还支持与Spring框架的集成,可以轻松地在Spring应用上下文中配置和管理事务。通过使用`@Transactional`注解,开发者可以在方法级别声明事务,简化事务管理。 总之,JOTM是实现Java分布式事务管理的强大...

    JOTM简单测试DEMO(不含jar包)

    这个DEMO可以帮助开发者理解如何在实际项目中集成JOTM和Spring进行分布式事务处理。需要注意的是,虽然DEMO中没有包含jar包,但你仍需自行获取并添加到项目中,否则无法正常运行。在实践中,根据具体的业务需求和...

    分布式事务JTA之实践:Spring+ATOMIKOS

    在实践过程中,首先需要在Spring配置文件中配置Atomikos事务管理器,包括设置事务超时时间、事务日志路径等参数。然后,为需要参与事务操作的数据源或消息队列注册为XAResources。接着,通过Spring的`@Transactional...

    Spring框架技术

    4. 使用Spring的事务注解或XML配置来指定哪些方法需要在JTA事务中执行。例如,假设有一个名为BbtForumImpl的类,其中的addTopic()方法需要在事务中运行,那么可以使用@Transactional注解标记这个方法,或者在Spring...

    开源事务管理器 JOTM.7z

    在实际应用中,JOTM 可能会与诸如 Spring 框架等进行整合,Spring 提供的事务管理抽象层使得与 JOTM 的集成变得更加简单。开发者可以利用 Spring 的 `@Transactional` 注解来自动管理事务的边界,提高代码的可读性...

    spring对多个数据库进行事务管理.doc

    在Spring中配置多个数据源并进行事务管理,可以参考以下步骤: 1. **配置数据源**:为每个数据库创建一个数据源Bean,例如`dataSource1`和`dataSource2`。这些数据源可以是基于JDBC的,也可以是其他ORM框架如...

    jotm 的 jar

    在JOTM的场景中,Spring可以用来配置和管理事务边界,通过声明式事务管理,使得在应用代码中无需显式调用事务开始和结束,而是由Spring自动处理,提高了代码的可读性和可维护性。 将这些组件整合在一起,开发者可以...

Global site tag (gtag.js) - Google Analytics