使用atomikos 如何实现 JTA/XA全局事务

写在前面的话

最近终于忙完了自考的事情,可以有更多的时间总结了。

久违的国家考试,听着广播里播放着考试相关的信息,以及感受着考场上紧张的氛围,突然还很怀念。

这样的机会真是越来越少呢。

什么是JTA

在介绍atomikos先介绍下JTA。

首先JTA是一个规范。

Java事务API(JTA:Java Transaction API)和它的同胞Java事务服务(JTS:Java Transaction Service),为J2EE平台提供了分布式事务服务(distributed transaction)的能力。

某种程度上,可以认为JTA规范是XA规范的Java版,其把XA规范中规定的DTP模型交互接口抽象成Java接口中的方法,并规定每个方法要实现什么样的功能。

这就把XA和JTA联系起来了。

JTA接口规范

JTA事务模型规定了一个分布式事务中有哪些组件,而JTA接口规范则规定这些组件之间如何交互。

需要注意的是JTA规范定义的这些接口,并不需要应用程序的开发人员去实现,而是由各个厂商去实现,根据在DTP模型中扮演的不同角色,需要实现不同的接口。

作为开发人员的我们只需要学会如何使用即可。

JTA规范是Java扩展包,在应用中需要额外引入相应的jar包依赖

<dependency>  

<groupId>javax.transaction</groupId>  

<artifactId>jta</artifactId>  

<version>1.1</version>

</dependency>

JTA规范1.1中的源码非常少,如下所示:

可以看到,这里除了红色框中包含的接口定义之外,其他全部是异常(XxxException),这里我们仅讨论JTA规范中定义的接口作用:

javax.transaction.Status:事务状态,这个接口主要是定义一些表示事务状态的常量,此接口无需实现

javax.transaction.Synchronization:同步

javax.transaction.Transaction:事务

javax.transaction.TransactionManager:事务管理器

javax.transaction.UserTransaction:用于声明一个分布式事务

javax.transaction.TransactionSynchronizationRegistry:事务同步注册

javax.transaction.xa.XAResource:定义RM提供给TM操作的接口

javax.transaction.xa.Xid:事务id

TM供应商

实现UserTransaction、TransactionManager、Transaction、TransactionSynchronizationRegistry、Synchronization、Xid接口,通过与XAResource接口交互来实现分布式事务。

此外,TM厂商如果要支持跨应用的分布式事务,那么还要实现JTS规范定义的接口。

常见的TM提供者包括我们前面提到的application server,包括:jboss、ejb server、weblogic等,以及一些以第三方类库形式提供事务管理器功能的jotm、Atomikos。

RM供应商

XAResource接口需要由资源管理器者来实现,XAResource接口中定义了一些方法,这些方法将会被TM进行调用,如:

start方法:开启事务分支

end方法:结束事务分支

prepare方法:准备提交

commit方法:提交

rollback方法:回滚

recover方法:列出所有处于PREPARED状态的事务分支

一些RM提供者,可能也会提供自己的Xid接口的实现。

特定接口

此外,不同的资源管理器有一些各自的特定接口要实现:

如JDBC2.0规范定义支持分布式事务的jdbc driver需要实现:javax.sql.XAConnection、javax.sql.XADataSource接口

JMS1.0规范规定支持分布式事务的JMS厂商,需要实现javax.jms.XAConnection、javax.jms.XASession接口

作为DTP模型中Application开发者的我们,并不需要去实现任何JTA规范中定义的接口,只需要使用TM提供的UserTransaction实现,来声明、提交、回滚一个分布式事务即可。

以下案例演示了UserTransaction接口的基本使用:构建一个分布式事务,来操作位于2个不同的数据库的数据,假设这两个库中都有一个user表。

UserTransaction userTransaction= new UserTransaction() {
        @Override
        public void begin() throws NotSupportedException, SystemException {
            
        }

        @Override
        public void commit() throws RollbackException, HeuristicMixedException, HeuristicRollbackException, SecurityException, IllegalStateException, SystemException {

        }

        @Override
        public void rollback() throws IllegalStateException, SecurityException, SystemException {

        }

        @Override
        public void setRollbackOnly() throws IllegalStateException, SystemException {

        }

        @Override
        public int getStatus() throws SystemException {
            return 0;
        }

        @Override
        public void setTransactionTimeout(int i) throws SystemException {

        }
    };
            try{     
                //开启分布式事务            
        try {
            userTransaction.begin();
        } catch (NotSupportedException e1) {
            e1.printStackTrace();
        } catch (SystemException e1) {
            e1.printStackTrace();
        }
        //  执行事务分支1            
                 conn1 = db1.getConnection();         
                   ps1= conn1.prepareStatement("INSERT into user(name,age) VALUES ('tianshouzhi',23)");        
                    ps1.executeUpdate();           
             //    执行事务分支2           
                 conn2 = db2.getConnection();      
        
                 ps2 = conn2.prepareStatement("INSERT into user(name,age) VALUES ('tianshouzhi',23)");      
                      ps2.executeUpdate();            
               //  提交,两阶段提交发生在这个方法内部       
                     userTransaction.commit();    
            }catch (Exception e){        
                try {             
                    userTransaction.rollback();//回滚     
                } catch (SystemException ignore) {  
                    
                } 
         }

需要注意的是,在分布式事务中,当我们需要提交或者回滚一个事务时,不应该再使用Connection接口提供的commit和rollback方法。

而是应该使用UserTransaction接口的commit接口和rollback接口替代。

另外,这个案例只是用于说明如何使用UserTransaction类,事实上,在实际开发中,并没有这么复杂。

一些开源的分布式事务解决方案,可以与spring声明式事务管理功能,因此我们可以通过一个简单@Transactional注解,即可实现分布式事务的功能。

例如,下面我们将要提到Atomikos,就支持与spring事务整合。

Atomikos介绍

Atomikos 是一个为Java平台提供增值服务的并且开源类事务管理器。

Atomikos TransactionsEssentials 是一个为Java平台提供增值服务的并且开源类事务管理器,以下是包括在这个开源版本中的一些功能:
1.全面崩溃 / 重启恢复

2.兼容标准的SUN公司JTA API

3.嵌套事务

4.为XA和非XA提供内置的JDBC适配器

Atomikos公司

Atomikos公司官方网址为 https://www.atomikos.com/。其旗下最著名的产品就是事务管理器。产品分两个版本:

TransactionEssentials:开源的免费产品

ExtremeTransactions:上商业版,需要收费。

开源版Atomikos-TransactionEssentials

TransactionEssentials:

1、实现了JTA/XA规范中的事务管理器(Transaction Manager)应该实现的相关接口,如:

UserTransaction实现是com.atomikos.icatch.jta.UserTransactionImp,用户只需要直接操作这个类

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.atomikos.icatch.jta;

import com.atomikos.icatch.config.UserTransactionService;
import com.atomikos.icatch.config.UserTransactionServiceImp;
import com.atomikos.util.SerializableObjectFactory;
import java.io.Serializable;
import javax.naming.NamingException;
import javax.naming.Reference;
import javax.naming.Referenceable;
import javax.transaction.HeuristicMixedException;
import javax.transaction.HeuristicRollbackException;
import javax.transaction.NotSupportedException;
import javax.transaction.RollbackException;
import javax.transaction.SystemException;
import javax.transaction.TransactionManager;
import javax.transaction.UserTransaction;

public class UserTransactionImp implements UserTransaction, Serializable, Referenceable {
    private static final long serialVersionUID = -865418426269785202L;
    private transient TransactionManager txmgr_;

    public UserTransactionImp() {
    }

    private void checkSetup() {
        Class var1 = TransactionManagerImp.class;
        synchronized(TransactionManagerImp.class) {
           
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值