使用 XADisk 的文件系统事务

XADisk 简介

Java™ 应用程序将它们的部分数据存储在文件中,可通过使用事务访问文件系统获得多方面的收益。了解如何使用开源的 XADisk 进行事务性文件访问。

Nitin Verma, 计算机科学家, Adobe Systems

Nitin Verma 的照片Nitin Verma 是 Adobe Systems 的一名 JavaEE 开发人员。他以前在 Oracle 工作,并参与开发 Oracle SOA Suite 的 JCA 适配器。XADisk 让他开始爱上了 JCA 和 XA。Nitin 毕业于 IIT 的计算机科学和工程专业。



2012 年 2 月 28 日

简介

许多 Java 应用程序,包括服务器端和桌面应用程序,都将它们的关键数据保存在文件系统、数据库或其他信息系统中。为实现与关键数据的安全、可靠的交互,应用程序开发人员常常依赖于对这些信息系统的事务性访问。典型的事务会提供明确的 ACID 属性,即原子性、一致性、隔离和耐久性。

目前的大多数数据库都支持事务。对于文件系统,此功能要么不可用,要么难以与 Java 应用程序集成。将事务与一系列文件/目录操作相关联,变得不可能或非常困难。而没有事务,就会存在在应用程序崩溃、对相同数据集进行并发访问和部分更改可见等期间出现意外结果的风险。

本文将介绍 XADisk,这是一个开源的综合事务系统,支持从 Java 和 JavaEE 应用程序对文件系统进行事务性访问。使用一些简单的 API,您可以将 XADisk 部署在任何 JVM 上,无需在操作系统上执行任何安装。部署之后,应用程序就会调用 XADisk API 在事务内执行各种各样的文件 IO 操作。

XADisk 还提供了其他许多功能,比如 XA 事务、完全的 JCA 合规性、入站消息等。这些功能不属于这篇简介文章的介绍范围。


XADisk 基本知识

可将 XADisk 视为应用程序与文件系统之间的一个层。XADisk 本身不是一种文件系统实现;它可用于各种各样的文件系统(比如 NTFS、FAT、ext3),并且支持应用程序对这些文件系统执行事务性访问。应用程序可调用 XADisk API 来执行各种 I/O 操作,以单个事务的形式提交或回滚所有这些操作。

XADisk 是使用 Java 编写的,在 Java 5 或其更高版本上运行。它可供所有类型的 Java 应用程序、在 Java 服务器中运行的 Web 应用程序(比如 Apache Tomcat)和在 JavaEE 服务器中运行 JavaEE 应用程序等使用。

作为 XADisk 用途的一个简单示例,可以考虑一个 Java 应用程序。这个应用程序希望创建一个名为 F1 的新文件,从另一个名为 F2 的文件向它写入一些数据,然后删除 F2。这 3 个操作可使用 XADisk 在单个事务内执行,并具有前面提及的 ACID 属性的典型迹象。即使应用程序在中途崩溃,XADisk 也会维护这些迹象。

XADisk 支持对文件/目录执行多种不同的操作:

  • 文件 — 创建、删除、移动、复制、截断、读取、写入、存在、getLength
  • 目录 — 创建、删除、移动、列出子目录、存在

当使用 XADisk 时,应用程序和目标文件系统需要在同一个机器上。应用程序可采用与部署在相同 JVM 上的 XADisk 相同的方式远程调用 XADisk API。

本文的剩余部分将介绍开始在任何 Java 应用程序中使用 XADisk 的一些简单步骤。


使用 XADisk

启动进程

在调用 XADisk IO 操作之前,应在一个 JVM 中启动一个 XADisk 实例。在相同 JVM 内,可以有多个 XADisk 实例;每个 XADisk 实例将拥有自己的隔离状态。本文将演示如何启动和调用这样一个 XADisk 实例。

就像您可以在任何 JVM 上启动 XADisk 一样,您可以在多种不同的 Java 环境中使用它,从简单的 Java 程序到 JavaEE 服务器(比如 JBoss)和 Web 服务器(比如 Tomcat)。

要启动一个 XADisk 实例,您的系统环境需要安装以下软件:

  1. Java5 或其更高版本
  2. XADisk.jar(从 http://xadisk.java.net/ 下载)
  3. JCA 1.5 Jar(从 http://download.java.net/maven/1/javax.resource/jars/connector-api-1.5.jar 下载)

在启动期间,XADisk 接受一个配置对象来提供它的各种配置选项。大部分配置属性都设置了自己的默认值。只有 SystemDirectoryInstanceId 是强制性属性。如 清单 1 中所示,configuration 构造函数接受者两个配置属性。SystemDirectory 是一个目录,XADisk 将其正常运行所需的所有工件(例如事务日志)保存在其中。InstanceId 惟一地标识 JVM 中的一个 XADisk 实例。

清单 1. 配置和初始化一个 XADisk 实例
String XADiskSystemDirectory =“/home/systems/XADiskSystem1";
StandaloneFileSystemConfiguration configuration = 
    new StandaloneFileSystemConfiguration(XADiskSystemDirectory, “instance-1”);
XAFileSystem xaf = XAFileSystemProxy.bootNativeXAFileSystem(configuration);
xaf.waitForBootup(10000L);

上面的序列完成一个 XADisk 实例的配置,并等待它完成启动过程。在启动完成后,此 XADisk 实例即可供相同 JVM 或远程 JVM 上的应用程序使用。

请注意,一个 XAFileSystem 类型的引用是开始调用 XADisk 实例上的操作的入口点。这个 XAFileSystem 引用可通过以下途径获得:

  1. 在启动期间,如 清单 1 中所示。
  2. 从 JVM 中的任何地方使用 instanceId,如 清单 2 中所示。
清单 2. 在相同 JVM 中获取 XADisk 实例的 XAFileSystem 引用。
XAFileSystem xaf = XAFileSystemProxy.getNativeXAFileSystemReference(“instance-1”);
  1. 通过远程应用程序获取,如 清单 3 中所示。
清单 3. 在远程 JVM 中获取 XADisk 实例的 XAFileSystem 引用。
XAFileSystem xaf = XAFileSystemProxy.getRemoteXAFileSystemReference("10.30.9.200", 5151);
/*the parameters are the serverAddress and serverPort configuration properties 
used during booting of the remote XADisk instance. Note that remoting to 
an XADisk instance is disabled by default and can be enabled 
using configuration.setEnableRemoteInvocations(true) during bootup*/

调用 IO 操作

XADisk 实例就绪后,就可以开始在文件/目录上执行事务性操作了。

获取 XAFileSystem 引用后,调用 XADisk API 的方法将保持相同,无论目标 XADisk 实例在相同 JVM 还是在远程 JVM 中运行。

所有文件/目录操作将在一个事务内发生,首先创建一个 Session 来启动一个事务,如 清单 4 中所示。

清单 4. 创建一个会话并启动一个事务
Session session = xaf.createSessionForLocalTransaction();

拥有会话后,即可根据需要执行 IO 操作。用于文件/目录操作的 XADisk API 非常简单。清单 5 给出了一些示例。

清单 5. 调用 XADisk API 来执行文件/目录操作
File f = new File("/testAPIs/test.txt");
if(session.fileExists(f)) {
    XAFileInputStream xis = session.createXAFileInputStream(f);
    for (int i = 0; i < 100; i++) {
        byte a = (byte) xis.read();
        if( a== -1) {
            break;
        }
        System.out.print(a);
     }
    xis.close();
    session.moveFile(f, new File("/testAPIs/test.txt___” + System.currentTimeMillis()));
}
else {
    //use false below to create file, true for directory
    session.createFile(f, false);
     //use false below for tiny write operations, true otherwise
     XAFileOutputStream xafos = session.createXAFileOutputStream(f, false);
     byte[] buffer = new byte[100];
     for (int i = 0; i < 100; i++) {
        buffer[i] = i*i;
     }
     xafos.write(buffer);
     xafos.close();
}
/* You can do more operations here, by calling Session APIs 
for reading/writing/creating/deleting/updating/copying/moving files 
and directories. For details, please see the XADisk JavaDoc for 
interface named XADiskBasicIOOperations.*/

完成所有 IO 操作后,我们只需调用该会话对象,即可提交(或回滚)该事务,如 清单 6 中所示。

清单 6. 提交或回滚与会话关联的事务
//commit the transaction
session.commit();
//or rollback the transaction
session.rollback();

要启动一个新事务,可创建一个新 Session 对象并执行 清单 5 中所示的相同步骤。

关闭

您可以从 JVM 中的任何地方关闭一个 XADisk 实例,如 清单 7 中所示。

清单 7. 从相同 JVM 关闭 XADisk 实例
XAFileSystem xaf = XAFileSystemProxy.getNativeXAFileSystemReference(“instance-1”);
xaf.shutdown();

结束语

通过在文件系统中应用事务,将关键数据保存在文件系统上的应用程序可获得显著效益。XADisk 是一个开源的、免费的解决方案,它使应用程序能够使用事务与文件系统交互。它提供了简单的 API 来初始化、执行各种文件/目录操作和管理事务。

XADisk 可执行的功能远不仅如此。请访问 参考资料 中的链接,获取有关的更多信息、示例代码和加入技术讨论。

参考资料

学习

获得产品和技术

  • XADisk 主页:查找更多 XADisk 信息,查阅用户指南,并获取 JavaDoc 和示例代码。
  • IBM 产品评估试用版软件:从试用版下载到在云中托管的产品,您可以使用专门面向开发人员的软件在下一个开源开发项目中实现创新。

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Open source, Java technology
ArticleID=796075
ArticleTitle=使用 XADisk 的文件系统事务
publish-date=02282012