Java-事务JTA

(145) 2024-04-13 09:01:02

简介

  JTA是一个分布式数据库事务的Java API规范,实现了该API的Trans cationManager支持分布式事务 -全局事务。
  解决了多数据库共同完成一个工作时,因不知道其它数据库执行状况,而无法选择提交或回滚的问题。

JAT的实现(由j2ee服务器提供商根据JTS规范提供)

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

XA规范

  底层数据库支持分布式事务管理,该数据库的驱动程序必须实现3个规范:

  • javax.sql.XADataSource 接口: XAConnection对象的工厂类
  • javax.sql.XAConnection 接口: 数据资源的连接功能
  • javax.sql.XAResource 接口: 数据资源:数据库或其他资源

DTP模型

  即分布式事务处理的模型规范,模型分为四部分:

  • 应用程序AP: 使用事务的应用
  • 事务管理器TM: 由数据库连接框架(Mybatis、Hibernate…)或JDBC提供实现JTA的管理器
  • 资源管理器RM: 数据库,通常为数据源。JDBC或第三方提供的datasource
  • 通信资源管理器CRM: 消息中间件

JTA的使用

JTA里面提供了 java.transaction.UserTransaction ,里面定义了下面几个方法
begin:开启一个事务
commit:提交当前事务
rollback:回滚当前事务
setRollbackOnly:把当前事务标记为回滚
setTransactionTimeout:设置事务的事件,超过这个事件,就抛出异常,回滚事务

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

学习链接

THE END

发表回复