`

JTA事务简述

 
阅读更多

Java事务API(Java Transaction API,简称JTA )是一个Java企业版的应用程序接口,在Java环境中,允许完成跨越多个XA资源的分布式事务。

 

JTA和它的同胞Java事务服务(JTS;Java TransactionService),为J2EE平台提供了分布式事务服务。不过JTA只是提供了一个接口,并没有提供具体的实现,而是由j2ee服务器提供商 根据JTS规范提供的,常见的JTA实现有以下几种:

1、J2EE容器所提供的JTA实现(JBoss)

2、独立的JTA实现:如JOTM,Atomikos.这些实现可以应用在那些不使用J2EE应用服务器的环境里用以提供分布事事务保证。如Tomcat,Jetty以及普通的java应用。

 

JTA里面提供了 java.transaction.UserTransaction ,里面定义了下面几个方法:

1、begin:开启一个事务

2、commit:提交当前事务

3、rollback:回滚当前事务

4、setRollbackOnly:把当前事务标记为回滚

5、setTransactionTimeout:设置事务的事件,超过这个事件,就抛出异常,回滚事务

 

这里,值得注意的是,不是使用了UserTransaction就能把普通的JDBC操作直接转成JTA操作,JTA对DataSource、Connection和Resource 都是有要求的,只有符合XA规范,并且实现了XA规范的相关接口的类才能参与到JTA事务中来,关于XA规范,目前主流的数据库都支持XA规范。

 

要想使用用 JTA 事务,那么就需要有一个实现javax.sql.XADataSource、javax.sql.XAConnection和javax.sql.XAResource接口的JDBC 驱动程序。一个实现了这些接口的驱动程序将可以参与 JTA 事务。一个 XADataSource 对象就是一个 XAConnection 对象的工厂。XAConnection 是参与 JTA 事务的 JDBC 连接。

 

要使用JTA事务,必须使用XADataSource来产生数据库连接,产生的连接为一个XA连接。

 

XA连接(javax.sql.XAConnection)和非XA(java.sql.Connection)连接的区别在于:XA可以参与JTA的事务,而且不支持自动提交。

 

public void JtaTransfer() { 
        javax.transaction.UserTransaction tx = null;
        java.sql.Connection conn = null;
         try{ 
             tx = (javax.transaction.UserTransaction) context.lookup("java:comp/UserTransaction");  //取得JTA事务,本例中是由Jboss容器管理
             javax.sql.DataSource ds = (javax.sql.DataSource) context.lookup("java:/XAOracleDS");  //取得数据库连接池,必须有支持XA的数据库、驱动程序  
             tx.begin();
            conn = ds.getConnection();
 
             // 将自动提交设置为 false,
             //若设置为 true 则数据库将会把每一次数据更新认定为一个事务并自动提交
             conn.setAutoCommit(false);
 
             stmt = conn.createStatement(); 
             // 将 A 账户中的金额减少 500 
             stmt.execute("\
             update t_account set amount = amount - 500 where account_id = 'A'");
             // 将 B 账户中的金额增加 500 
             stmt.execute("\
             update t_account set amount = amount + 500 where account_id = 'B'");
 
             // 提交事务

              tx.commit();

             // 事务提交:转账的两步操作同时成功

         } catch(SQLException sqle){            

             try{ 

                 // 发生异常,回滚在本事务中的操做

              tx.rollback();

                 // 事务回滚:转账的两步操作完全撤销

                 stmt.close(); 

                 conn.close(); 

             }catch(Exception ignore){ 

 

             } 

             sqle.printStackTrace(); 

         } 

     }

上面的例子就是一个使用JTA事务的转账操作,该操作相对依赖于J2EE容器,并且需要通过JNDI的方式获取UserTransaction和Connection。

 

标准的分布式事务

 

一个分布式事务(Distributed Transaction)包括一个事务管理器(transaction manager)和一个或多个资源管理器(resource manager)。一个资源管理器(resource manager)是任意类型的持久化数据存储。事务管理器(transaction manager)承担着所有事务参与单元者的相互通讯的责任,JTA的实现方式也是基于以上这些分布式事务参与者实现的。

 

JTA的优缺点(标准的JTA方式的事务管理在日常开发中并不常用)

优点:提供了分布式事务的解决方案,严格的ACID。

缺点:

1、实现复杂

2、通常情况下,JTA UserTransaction需要从JNDI获取。这意味着,如果我们使用JTA,就需要同时使用JTA和JNDI。

3、JTA本身就是个笨重的API,通常JTA只能在应用服务器环境下使用,因此使用JTA会限制代码的复用性。

 

总结

Java事务的类型有三种:JDBC事务、JTA(Java Transaction API)事务、容器事务,其中JDBC的事务操作用法比较简单,适合于处理同一个数据源的操作。JTA事务相对复杂,可以用于处理跨多个数据库的事务,是分布式事务的一种解决方案。

 

这里还要简单说一下,虽然JTA事务是Java提供的可用于分布式事务的一套API,但是不同的J2EE平台的实现都不一样,并且都不是很方便使用,所以,一般在项目中不太使用这种较为复杂的API。现在业内比较常用的分布式事务解决方案主要有异步消息确保型、TCC、最大努力通知等。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics