Apache Commons Transaction 旨在提供一个轻量级、标准化、高效的 Java 事务多线程编程的工具包,实现了多级锁、事务集合和事务级文件访问。
事务处理系统对数据库使用者来说,是非常熟悉的事情;但是如果将事务处理系统从数据库转移到文件系统上,估计很多同学都要一筹莫展了。实际上,无论库/框架、语言,或者文件系统级别,对文件系统操作事务的支持一直都很薄弱。
单独看一些文件系统操作(比如文件重命名、删除等),它们是原子的,但是从目前的情况看,很少有解决办法能够形成一组综合的API,全方位地支持事务性的文件IO操作。如果文件操作(例如创建、修改、重命名、删除文件)需要作为事务的一部分而连贯地执行,那么应用程序往往必须依赖于自行设计的方案,去减少系统/应用失败或并发访问时出现不一致状态的可能性。
Apache CommonsTransaction就是在这方面做的一些努力。
Apache Commons Transaction项目的目标之一是提供对文件系统的事务性访问,它的实现方式是与具体的文件系统提供者/实现无关的。这个Java库用一种悲观锁定方案来实现文件系统上的ACID事务。
Apache CommonsTransaction的核心组件是FileResourceManager,FileResourceManager创建事务、协调它掌管下的资源/文件的文件操作——复制、创建、删除、移动、写入,以及准备和提交事务。在初始化阶段要为FileResourceManager准备:
· 提交之后存放主要数据的目录
· 事务存储临时数据的目录(工作目录)
· 指示是否要对路径进行URL编码的布尔标记
· FileResourceManager使用的日志器(logger)
启动之后,FileResourceManager紧接着将试图回滚所有未完成的事务,除非事务在系统失败或者FileResourceManager遇到不可挽回的问题时已经在提交的过程中了,在这种情况下,FileResourceManager会试图前滚事务。万一事务不能恢复,例如既不能回滚、也不能前滚,整个工作目录会由FileResourceManger标记为“脏”状态,在问题解决之前都不再允许对其进行修改。日志中的信息通常都可以帮助从“脏”状态进行手动恢复。
下面这些代码,是简单的用Apache Commons Transaction实现文件事务系统
packagetest.ffm83.commons.transcation;
importorg.apache.commons.logging.Log;
importorg.apache.commons.logging.LogFactory;
importorg.apache.commons.transaction.file.FileResourceManager;
importorg.apache.commons.transaction.file.ResourceManagerException;
importorg.apache.commons.transaction.util.CommonsLoggingLogger;
importorg.apache.commons.transaction.util.LoggerFacade;
/**
* 通过commons Transaction 进行简单的文件系统的事务控制
* 这里的log是commons-transaction包中的类
* 本应用需要导入额外的jta 相关jar包
* @author 范芳铭
*/
publicclass TransactionUsage {
public static void main(String[] args){
Log log =LogFactory.getLog(TransactionUsage.class);
LoggerFacade logger = newCommonsLoggingLogger(log);
//工作目录
String workDir ="D:/ffm83/work/";
//临时数据存放目录
String tempDir ="D:/ffm83/temp";
// 构造函数的第三个参数:false,标识是否encoding文档的url,这个一般不需要设置为true
FileResourceManager frm = newFileResourceManager(workDir, tempDir,false, logger);
String txId = "";
try {
// 这标识frm的状态为start
frm.start();
txId =frm.generatedUniqueTxId(); //获取事物ID
// 开启Transaction
frm.startTransaction(txId);
frm.deleteResource(txId,"ffm83.txt");
System.out.println("删除本目录下的文件成功");
// 提交事务
frm.commitTransaction(txId);
} catch (Exception e) {
try {
// 回滚事务
frm.rollbackTransaction(txId);
System.out.println("删除本目录下的文件失败,回滚。");
}catch (ResourceManagerException e1) {
e1.printStackTrace();
}
}
}
}
运行结果如下:
删除本目录下的文件成功