JTA的实际交付价值是多少?

时间:2014-06-28 01:27:23

标签: java jta bitronix

我正试图围绕Java Transactions API(JTA)及其中一个实现Bitronix下的。但随着我对文档的深入挖掘,我不禁想到以下简单的例子:

public interface Transactional {
    public void commit(Object);
    public void rollback();
}

public class TransactionalFileWriter extends FileWriter implements Transactional {
    @Override
    public void commit(Object obj) {
        String str = (String)obj;

        // Write the String to a file.
        write(str);
    }

    @Override
    public void rollback() {
        // Obtain a handler to the File we are writing to, and delete the file.
        // This returns the file system to the state it was in before we created a file and started writing to it.
        File f = getFile();

        // This is just pseudo-code for the sake of this example.
        File.delete(f);
    }
}

// Some method in a class somewhere...
public void doSomething(File someFile) {
    TransactionalFileWriter txFileWriter = getTxFW(someFile);
    try {
        txFileWriter.commit("Create the file and write this message to it.");
    } catch(Throwable t) {
        txFileWriter.rollback();
    }
}

不要过于关注上面的实际代码。这个想法很简单:一个事务文件编写器,它创建一个文件并写入它。它的rollback()方法删除文件,从而使文件系统返回到commit(Object)之前的状态。

我在这里遗漏了什么吗?这是JTA的全部优惠吗?或者是否有一整套与事务性不同的维度/方面,而上面的简单例子没有表示?我猜测后者,但还没有看到JTA文档中的任何具体内容。如果我遗失了什么,那么它是什么,有人可以告诉我具体的例子?我可以看到事务性是JDBC的一个重要组成部分,但希望能够通过数据库以外的其他方式获取JTA的示例。

2 个答案:

答案 0 :(得分:7)

正如其他人提到的那样,JTA的主要好处不是单一交易案例,而是多笔交易的编排。

在适当的环境中使用时,您的“交易文件”是一个很好的概念性示例。

考虑一个人为的用例。

您正在上传包含关联元数据的图片,然后您希望警告基础结构该文件已到达。

这个“简单”的任务充满了可靠性问题。

例如,此工作流程:

String pathName = saveUploadedFile(myFile);
saveMetaData(myFile.size(), myFile.type(), currentUser, pathName);
queueMessageToJMS(new FileArrivalEvent(user, pathName);

这段代码涉及文件系统和2个不同的服务器(DB和JMS)。

如果saveUploadedFile成功,但saveMetaData没有,那么你现在在文件系统上有一个孤立文件,可以说是“文件泄漏”。如果saveMetaData成功,但队列没有,则保存了文件,但“没人知道”。交易的成功依赖于所有3个组件成功执行其任务。

现在,抛出JTA(不是真正的代码):

beginWork();
try {
    String pathName = saveUploadedFile(myFile);
    saveMetaData(myFile.size(), myFile.type(), currentUser, pathName);
    queueMessageToJMS(new FileArrivalEvent(user, pathName);
} catch(Exception e) {
    rollbackWork();
} finally {
    commitWork();
}

现在它“全部有效”,或“没有任何效果”。

由于大多数系统没有事务管理器,因此通常人们会通过箍来使这种事情安全地工作。但是通过事务管理器(即JTA),您可以为TM管理所有的环节,并且可以保持代码清洁。

如果您对行业进行调查,您会发现很少有交易管理人员。最初它们是“企业”级系统使用的专有程序。 TIBCO是着名的,IBM有一个,微软有一个。 Tuxedo过去很受欢迎。

但是对于Java和JTA,以及无处不在的Java EE(等)服务器,“每个人”都有一个事务管理器。我们在Java世界中获得这个“免费”的编排。而且它很方便。

Java EE使事务管理器无处不在,而事务处理则考虑了背景。 Java EE意味着“永远不必再次编写commit()”。 (显然Spring提供类似的设施)。

对于大多数系统,没有必要。这就是为什么大多数人不太了解它,或者根本不会错过它。大多数系统都填充单个数据库,或者根本不担心围绕多个系统编排的问题。这个过程可能是有损的,他们已经建立了自己的清理机制,无论如何。

但是当你需要它时,它非常好。同时致力于多个系统可以解决很多麻烦。

答案 1 :(得分:1)

JTA的最大特点是您可以在一个应用程序中组合多个事务存储,并运行跨越这些独立存储的事务。

例如,您可以拥有一个数据库,一个分布式事务键值存储和简单的FileWriter,并拥有一个对所有这些执行操作的事务,并一次性提交所有存储中的所有更改。

看看infinispan。这是一个交易数据网格,它使用JTA,可以与其他JTA交易服务结合使用。

修改

基本上,JTA连接到X/Open XA标准,它提供了直接在Java代码中与X / Open XA资源交互的方法。您可以使用具有X / Open XA兼容资源的alredy现有数据存储,例如数据库,分布式数据网格等。或者,您可以通过实施javax.transaction.xa.XAResource来定义自己的资源。然后,当您的User transaction使用这些资源时,无论资源位于何处,事务管理器都会为您编排所有数据存储。

整个业务由负责同步独立数据存储的事务管理器管理。 JTA没有提供交易管理器。 JTA只是一个API。如果你愿意(javax.transaction.TransactionManager),你可以写自己的,但显然这是一项艰巨的任务。相反,你想要的是使用一些已经实现的JTA服务/库,它具有事务管理器。例如,如果在应用程序中使用infinispan,则可以使用其事务管理器来允许事务与不同的数据存储进行交互。最好从JTA接口的实现者那里寻求有关如何实现这一目标的更多信息。

您可以找到完整的JTA API文档here,尽管它很长。还有一些tutorials可以讨论如何使用Java EE事务管理器并更新多个数据存储,但它非常模糊,并且不提供任何代码示例。

您可以查看Infinispan的文档和教程,但我看不到任何将Infinispan与其他数据存储相结合的示例。

编辑2:

要从评论中回答您的问题:您的理解或多或少是正确的,但我会尝试进一步澄清。

更容易解释架构并用图片回答您的问题。以下内容摘自JTA规范1.1

这是X / Open XA架构:

X/Open XA achitecture

每个数据存储(数据库,消息队列,SAP ERP系统等)都有自己的资源管理器。对于关系数据库,JDBC驱动程序是一个资源适配器,它表示Java中数据库的资源管理器。每个资源都必须通过XAResource接口提供(这样,即使不知道特定数据存储的实现细节,事务管理器也可以管理它们)。

您的应用程序通过资源适配器与资源管理器(以访问特定资源)以及UserTransaction接口与事务管理器(启动/完成事务)进行通信。每个资源管理器都需要首先进行初始化,并且必须为全局事务配置(即跨越多个数据存储)。

基本上,是的,数据存储是对某些资源进行分组的独立逻辑单元。它们还展示了允许执行本地事务的接口(仅限于特定的数据存储)。此接口可能性能更好,或者可能会暴露某些特定于该数据存储的附加功能,而这些功能是通过JTA接口无法实现的。

这是JTA环境的架构:

JTA architecture

小半圆代表JTA界面。在您的情况下,您最感兴趣的是JTA UserTransaction界面。您也可以使用EJB(事务bean),Application Server将为您管理事务,但这是一种不同的方式。

  

从事务管理器的角度来看,实际执行了   交易服务不需要暴露;只需要高级接口   定义为允许事务划分,资源登记,同步和   从交易服务的用户驱动的恢复过程。

因此,事务管理器可以理解为仅代表用于管理事务(如JTS实现)的实际机制的接口,但是将其视为一个整体并不是错误。

据我所知,如果您运行JBoss应用程序服务器,那么您已经配备了具有基础事务服务实现的事务管理器。