`
msh24
  • 浏览: 57627 次
  • 性别: Icon_minigender_1
  • 来自: 山西
文章分类
社区版块
存档分类
最新评论

tomcat 使用jotm+aop支持jta(转载)

阅读更多


   jotm 包括 jotm-core.jar、ow2-connector-1.5-spec.jar、jotm-client.jar、xapool.jar。

   jotm-core.jar、ow2-connector-1.5-spec.jar、jotm-client.jar 主要是提供对transaction 的管理。

xapool.jar提供 xa datesource  以及 connection  pool 。


   其实个人觉得 学习jta 的切入点只有一个 ,为什么要使用 xa datesource  ,而且要求是如此的强烈,以至于让我很想弄明白。

    一般的解释就是:JTA(Java Transaction API) 为 J2EE 平台提供了分布式事务服务。要用 JTA 进行事务界定,应用程序要调用 javax.transaction.UserTransaction 接口中的方法。例如:
  utx.begin();
  // ...
  DataSource ds = obtainXADataSource();
  Connection conn = ds.getConnection();
  pstmt = conn.prepareStatement("UPDATE MOVIES ...");
  pstmt.setString(1, "Spinal Tap");
  pstmt.executeUpdate();
  // ...
  utx.commit();

“用 JTA 界定事务,那么就需要有一个实现 javax.sql.XADataSource 、 javax.sql.XAConnection 和 javax.sql.XAResource 接口的 JDBC 驱动程序。一个实现了这些接口的驱动程序将可以参与 JTA 事务。一个 XADataSource 对象就是一个 XAConnection 对象的工厂。 XAConnection s 是参与 JTA 事务的 JDBC 连接。”
  要使用JTA事务,必须使用XADataSource来产生数据库连接,产生的连接为一个XA连接。

JTA方式的实现过程:
  用XADataSource产生的XAConnection它扩展了一个getXAResource()方法,事务通过这个方法把它加入到事务容器中进行管理。

[---------------------来至baidu---------------------]


    但我觉得还是不能理解,问题是还不能解释我原来提出的切入点[为什么要使用 xa datesource],能解释的只有一句话:用XADataSource产生的XAConnection它扩展了一个getXAResource()方法,事务通过这个方法把它加入到事务容器中进行管理,显然这不能让人满意!

    所以我要解释的就是 jta 为什么只能使用xa datesource,要解释这一点,我们要先了解 普通的 jdbc transaction[hibernate transaction] 又是一个什么原理:在这里我结合 spring aop 讲解 jdbc transaction[hibernate transaction] 
            
    这是jdbc transaction[hibernate transaction] 使用 spring aop 的配置:

             <!-- dataSource  其实已经被c3p0 包装过了 -->
             <bean id="dataSource"
        class="com.mchange.v2.c3p0.ComboPooledDataSource"
        destroy-method="close" dependency-check="none">
        <property name="driverClass">
            <value>${datasource.driverClassName}</value>
        </property>
        <property name="jdbcUrl">
            <value>${datasource.url}</value>
        </property>
        <property name="user">
            <value>${datasource.username}</value>
        </property>
        <property name="password">
            <value>${datasource.password}</value>
        </property>
        <property name="acquireIncrement">
            <value>${c3p0.acquireIncrement}</value>
        </property>
        <property name="initialPoolSize">
            <value>${c3p0.initialPoolSize}</value>
        </property>
        <property name="minPoolSize">
            <value>${c3p0.minPoolSize}</value>
        </property>
        <property name="maxPoolSize">
            <value>${c3p0.maxPoolSize}</value>
        </property>
        <property name="maxIdleTime">
            <value>${c3p0.maxIdleTime}</value>
        </property>
        <property name="idleConnectionTestPeriod">
            <value>${c3p0.idleConnectionTestPeriod}</value>
        </property>
        <property name="maxStatements">
            <value>${c3p0.maxStatements}</value>
        </property>
        <property name="numHelperThreads">
            <value>${c3p0.numHelperThreads}</value>
        </property>
    </bean>

        <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource">
            <ref local="dataSource" />
        </property>
        <property name="mappingResources">
                      ......内容太多 ,不在显示
        </property>
    </bean>


        <!-- transactionManager-->
        <bean id="myTransactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory">
            <ref local="sessionFactory" />
        </property>
    </bean>

        <!-- 配置事务处理 -->
    <bean id="txProxyTemplate" abstract="true"
        class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <property name="transactionManager">
            <ref bean="myTransactionManager" />
        </property>
        <property name="transactionAttributes">
               ....拦截 dao 或 service 的配置
        </property>
    </bean>


我们将sessionFactory 传给了transactionManager、然后transactionManager 传给TransactionProxyFactoryBean
然后我们一般还会配置 dao ,例如  [把sessionFactory 传给  dao]
         <bean id="permissionDAO"
        class="sezelee.sample.bbsse.dao.hibernate.PermissionHibernateDAO">
        <property name="sessionFactory">
            <ref local="sessionFactory" />
        </property>
    </bean>

好,现在说 permissionDAO 的事务拦截的调用过程[关注的是transaction 的流向]:

假设代码 调用 permissionDAO  的某个方法之前事务拦截,我们就从TransactionProxyFactoryBean 中myTransactionManager中获取connection ,然后获取 transaction 事务。

说明 :myTransactionManager中已经有 sessionFactory ,我们就是从sessionFactory中获取connection ,然后由connection 获取transaction ,sessionFactory 获取connection 的时候,就将connection  放入 threadlocal[和线程绑定]。

下面正式执行我们的业务逻辑:比如permissionDAO 中的 save(); save()中必然要使用到数据库的connection 。我们从哪里获取 呢, permissionDAO中不是有传进sessionFactory 吗?和myTransactionManager 从sessionFactory获取connention 的道理一样, save()中用到的 connection也从 sessionFactory 获取,那么 此时从sessionFactory 获取的connection就是之前放入threadlocal的connection ,save() 执行完毕。

    在提交[commit]或回滚[rollback] 的时候我们获取的还是之前放入threadlocal的connection ,为此整个事务的开始到结束 我们使用的都是 同一个 connection。

    这就是 普通 jdbc transaction 结合 spring aop


    那 jta 又是怎么个情况呢?

    我们直接从 jta 使用spring aop 的配置入手。

      <!-- jta 事务-->
    <bean id="jotm" class="org.springframework.transaction.jta.JotmFactoryBean" />
  
    <bean id="jtaTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
        <property name="userTransaction" ref="jotm" />
    </bean>

        <!-- XAdataSource-->
    <bean id="innerDataSource" class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown">
      <property name="transactionManager" ref="jotm"/>
    
        <property name="driverName">
            <value>${datasource.driverClassName}</value>
        </property>
        <property name="url">
            <value>${datasource.url}</value>
        </property>
        <property name="user">
            <value>${datasource.username}</value>
        </property>
        <property name="password">
            <value>${datasource.password}</value>
        </property>
      
           <property name="maxCon" value="50" />
           <property name="minCon" value="5" />
           <property name="preparedStmtCacheSize" value="5"/>
    </bean>
  
    <!-- 对  innerDataSource 进行pool 包装-->
    <bean id="dataSource" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown">
       <property name="dataSource" ref="innerDataSource"/>
       
       <property name="user" value="root"/>
       <property name="password" value=""/>
       <property name="minSize" value="2"/>
       <property name="maxSize" value="50"/>
       <property name="deadLockMaxWait" value="1000"/>
       <property name="deadLockRetryWait" value="600"/>
    </bean>


     <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource">
            <ref local="dataSource" />
        </property>
        <property name="mappingResources">
                    ......
        </property>  
    </bean>



       <!-- 配置事务处理 -->
    <bean id="txProxyTemplate" abstract="true"
        class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <property name="transactionManager">
            <ref bean="jtaTransactionManager" />
        </property>
        <property name="transactionAttributes">
            .....
        </property>
    </bean>
    <!-- 配置事物处理 -->


        <!-- about permission DAO -->
    <bean id="permissionDAO"
        class="sezelee.sample.bbsse.dao.hibernate.PermissionHibernateDAO">
        <property name="sessionFactory">
            <ref local="sessionFactory" />
        </property>
    </bean>


   那么这段代码和 上面的jdbc transaction 有什么不同呢 ?

   此时 transactionManager[jtaTransactionManager] 传入的不在是sessionFactory ,而是 jtom。

   jtom 到底是什么 呢 ,不用着急我们 往下看, 仔细看 innerDataSource 有什么不同,多了一个jotm。

    这是为什么呢?
    我们还是从 permissionDAO 的事务拦截的调用过程 开始  [关注的是transaction 的流向]:

    假设代码 调用 permissionDAO  的某个方法之前事务拦截,
比如说 update() 方法: 里面需要获取 两个 connection [来至不同的数据源]。

    比如 第一个来至 datesource1  、 第二个来至 datesource2
还记得 innerDataSource 中 配置的jtom 吗?
    通过 sessionFactory  我们获取 第一个 datesource1 的 connention 时 将connention 放入jtom。我们获取 第二个 datesource2 的 connention 时将connention 放入jtom

    jtom 也同时传到了jtaTransactionManager ,update() 方法业务执行完毕。

     在提交[commit]或回滚[rollback] 的时候 ,我们就从 jtaTransactionManager 中 的 jtom 获取datesource1 的 connention、datesource2 的 connention

    然后加上这样的逻辑 ,只要其中有一个异常 ,就全部rollback。
                           try{                     datesource1.connention.transaction.commit                                datesource2.connention.transaction.commit
                            }catch(Exception e){
                                 datesource1.connention.transaction.rollback
                                 datesource2.connention.transaction.rollback
                            }

所以我们 进行数据库操作的 connention 都是放入jtom或从jtom获取[其实jtom 的connection 还是 绑定到 threadlocal] 。


    我们 就简单的将 jtom 理解为 一个 map ,  获取connection 时将 connection放入这个map。然后 我们 将map 传给transactionManager ,当事务要提交/回滚的时候我们从transactionManager 获取这个map
spring 给我们提供了这样一个transactionManager [jtatransactionManager]。


     以上就是对[用XADataSource产生的XAConnection它扩展了一个getXAResource()方法,事务通过这个方法把它加入到事务容器中进行管理] 这句话的解释。

     到此我们 回到 刚开始的切入点:为什么要使用 xa datesource。

     xa datesource 提供了 在获取 connecntion时 将connecntion放入 jtom 的支持。

     而 datesource 是没有提供这种 支持的。

     好了 !全文结束 ,以上是我对 jta 的个人理解 ,有不对的地方,请大家指点!
分享到:
评论

相关推荐

    spring+jotm+ibatis+mysql实现JTA分布式事务

    本项目“spring+jotm+ibatis+mysql实现JTA分布式事务”旨在利用这些技术来确保在分布式环境中的数据一致性。下面将详细介绍这个项目所涉及的知识点。 首先,Spring框架是Java开发中最常用的应用框架之一,它提供了...

    Spring+Jotm+Hibernate+Oracle+Junit 实现JTA分布式事务要求Demo工程

    2.Spring+Jotm整合实现JTA分布式事务,应用场景如转账等,同一事务内完成db1用户加100元、db2用户减100元。 3.Spring+Junit4单元测试,优点:不会破坏数据库现场,等等。 (特别注意:Spring3.0里不在提供对jotm的...

    Spring+iBatis+JOTM实现JTA事务

    JOTM作为JTA的一个实现,提供了这些接口的具体实现,使得开发者可以不依赖于特定的应用服务器就能使用JTA功能。 在集成Spring+iBatis+JOTM的环境中,Spring主要负责事务策略的配置和管理,iBatis则作为持久层框架,...

    struts + spring + hibernate + velocity + ajax + jotm + acegi

    简介: struts + spring + hibernate + velocity + ajax + jotm + acegi ================================================================================================ 本资料共包含以下附件: 1161...

    hibernate+tomca5.5t+JOTM 2.10 JTA配置

    标题 "hibernate+tomcat5.5+JOTM 2.10 JTA配置" 涉及的是在Java环境下使用Hibernate ORM框架与Tomcat 5.5应用服务器,以及集成JOTM(Java Open Transaction Manager)进行JTA(Java Transaction API)管理的配置过程...

    Tomcat中使用JOTM2.14

    标题“Tomcat中使用JOTM2.14”指的是在Apache Tomcat服务器中集成并使用JOTM(Java Open Transaction Manager)版本2.14的过程。JOTM是一个开源的事务管理器,用于处理Java应用程序中的ACID(原子性、一致性、隔离性...

    Java分布式开发spring+jta+jotm

    在Spring中使用JTA和JOTM,首先需要在项目中引入JOTM的依赖。接着,你需要配置Spring的`DefaultJtaPlatform`和`JtaTransactionManager`。`DefaultJtaPlatform`指定了JOTM作为事务管理器,而`JtaTransactionManager`...

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

    本教程将深入探讨如何使用Spring框架、Java Transaction API (JTA) 和 Java Open Transaction Manager (JOTM) 来实现这样的分布式事务管理。 首先,我们来了解一下JTA。JTA是Java平台的标准事务API,它允许应用程序...

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

    本文将深入探讨如何在Tomcat应用服务器上集成JTA,并使用JOTM(Java Open Transaction Manager)或Atomikos作为事务管理器来实现分布式事务。 首先,我们需要理解JTA的核心概念。JTA是Java EE平台的一部分,提供了...

    JBPM5.1入门学习

    4.3.4 使用jotm配置tomcat 数据源以支持JTA 25 4.3.5 Jbpm相关配置文件更新 29 4.3.6 Java服务器端编码 31 4.3.7 Jsp客户端编码 50 4.3.8 Struts和spring的配置 52 4.4 部署和运行 54 4.4.1 启动Demo Human Task ...

    多数据源 更新 spring jta java jotm

    本文将深入探讨如何使用Spring、Java Transaction API (JTA) 和 Java Object Transaction Manager (JOTM) 实现多数据源更新的解决方案。 首先,让我们理解什么是多数据源。在传统的单数据源环境中,应用程序通常...

    spring下jotm jta实现小结

    NULL 博文链接:https://liangzhijian.iteye.com/blog/1404534

    JTA事务源码示例

    Spring+iBatis+JOTM实现JTA事务: 如何处理跨库事物:spring + jtom 的jta事务是个很好的选择. 这个源码示例非常不错,包括所有的源码和jar包,下载后eclipse 或 myeclipse 导入就能用。 里面有详细的说明和注释,...

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

    为了能够顺利地在项目中使用JOTM进行事务管理,首先需要将以下JAR包加入到Tomcat的lib目录中: - `jotm.jar`: JOTM核心库。 - `jotm_jrmp_stubs.jar`: JOTM JRMP远程调用相关的类库。 - `ow_carol.jar`: 提供了与...

    在Spring中使用JTA事务管理

    无论是集成JOTM还是引用Tomcat内置的JTA支持,都能实现跨数据库的事务一致性。这在处理分布式系统或多数据源的应用中至关重要,因为它确保了即使在异常情况下,数据也能保持一致性和完整性。在实际应用中,你可能还...

    jonas_timer-1.4.3.jar 、jotm-1.4.3.jar、jta-1.0.1B.jar

    标题中的三个文件——"jonas_timer-1.4.3.jar"、"jotm-1.4.3.jar"和"jta-1.0.1B.jar",是Java开发中的关键组件,主要用于分布式事务处理和定时任务管理。在Java应用程序中,特别是企业级应用,这些库文件扮演着至关...

Global site tag (gtag.js) - Google Analytics